diff --git a/.github/workflows/generate-docs-pdf.yml b/.github/workflows/generate-docs-pdf.yml new file mode 100644 index 0000000..b721227 --- /dev/null +++ b/.github/workflows/generate-docs-pdf.yml @@ -0,0 +1,133 @@ +name: Generate Documentation PDFs + +on: + push: + branches: ["main", "v2.0.0"] + paths: + - 'gh_pages/_docs/**' + - 'gh_pages/assets/pdf-template/**' + - '.github/workflows/generate-docs-pdf.yml' + workflow_dispatch: + +permissions: + contents: write + +jobs: + generate-pdfs: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Install Pandoc and LaTeX + run: | + sudo apt-get update + sudo apt-get install -y pandoc texlive-latex-base texlive-fonts-recommended texlive-fonts-extra texlive-latex-extra + + - name: Create PDF output directory + run: | + mkdir -p gh_pages/assets/pdf + + - name: Generate Getting Started PDF + run: | + pandoc gh_pages/_docs/getting-started.md \ + -o gh_pages/assets/pdf/getting-started.pdf \ + --from markdown \ + --template gh_pages/assets/pdf-template/template.tex \ + --variable documentclass=article \ + --variable geometry:margin=1in \ + --variable fontsize=11pt \ + --variable colorlinks=true \ + --variable linkcolor=red \ + --variable urlcolor=red \ + --toc \ + --toc-depth=2 \ + --pdf-engine=pdflatex \ + --metadata title="Event Video Playback - Getting Started" \ + --metadata author="Beckhoff USA Community" + + - name: Generate PLC Library Usage PDF + run: | + pandoc gh_pages/_docs/plc-usage.md \ + -o gh_pages/assets/pdf/plc-usage.pdf \ + --from markdown \ + --template gh_pages/assets/pdf-template/template.tex \ + --variable documentclass=article \ + --variable geometry:margin=1in \ + --variable fontsize=11pt \ + --variable colorlinks=true \ + --variable linkcolor=red \ + --variable urlcolor=red \ + --toc \ + --toc-depth=2 \ + --pdf-engine=pdflatex \ + --metadata title="Event Video Playback - PLC Library Usage" \ + --metadata author="Beckhoff USA Community" + + - name: Generate Service Configuration PDF + run: | + pandoc gh_pages/_docs/service-config.md \ + -o gh_pages/assets/pdf/service-config.pdf \ + --from markdown \ + --template gh_pages/assets/pdf-template/template.tex \ + --variable documentclass=article \ + --variable geometry:margin=1in \ + --variable fontsize=11pt \ + --variable colorlinks=true \ + --variable linkcolor=red \ + --variable urlcolor=red \ + --toc \ + --toc-depth=2 \ + --pdf-engine=pdflatex \ + --metadata title="Event Video Playback - Service Configuration" \ + --metadata author="Beckhoff USA Community" + + - name: Generate HMI Usage PDF + run: | + pandoc gh_pages/_docs/hmi-usage.md \ + -o gh_pages/assets/pdf/hmi-usage.pdf \ + --from markdown \ + --template gh_pages/assets/pdf-template/template.tex \ + --variable documentclass=article \ + --variable geometry:margin=1in \ + --variable fontsize=11pt \ + --variable colorlinks=true \ + --variable linkcolor=red \ + --variable urlcolor=red \ + --toc \ + --toc-depth=2 \ + --pdf-engine=pdflatex \ + --metadata title="Event Video Playback - HMI NuGet Package Usage" \ + --metadata author="Beckhoff USA Community" + + - name: Generate Complete Documentation PDF + run: | + pandoc gh_pages/_docs/getting-started.md \ + gh_pages/_docs/plc-usage.md \ + gh_pages/_docs/service-config.md \ + gh_pages/_docs/hmi-usage.md \ + -o gh_pages/assets/pdf/complete-documentation.pdf \ + --from markdown \ + --template gh_pages/assets/pdf-template/template.tex \ + --variable documentclass=report \ + --variable geometry:margin=1in \ + --variable fontsize=11pt \ + --variable colorlinks=true \ + --variable linkcolor=red \ + --variable urlcolor=red \ + --toc \ + --toc-depth=2 \ + --pdf-engine=pdflatex \ + --metadata title="Event Video Playback - Complete Documentation" \ + --metadata author="Beckhoff USA Community" \ + --metadata date="$(date +'%B %Y')" + + - name: Commit PDFs to repository + run: | + git config --local user.email "github-actions[bot]@users.noreply.github.com" + git config --local user.name "github-actions[bot]" + git add gh_pages/assets/pdf/*.pdf + git diff --staged --quiet || git commit -m "Generate documentation PDFs [skip ci]" + git push diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml new file mode 100644 index 0000000..175f24f --- /dev/null +++ b/.github/workflows/pages.yml @@ -0,0 +1,58 @@ +name: Deploy Jekyll site to GitHub Pages + +on: + push: + branches: ["main", "v2.0.0"] + paths: + - 'gh_pages/**' + - '.github/workflows/pages.yml' + workflow_dispatch: + +permissions: + contents: read + pages: write + id-token: write + +concurrency: + group: "pages" + cancel-in-progress: false + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: '3.3' + bundler-cache: true + working-directory: ./gh_pages + + - name: Setup Pages + id: pages + uses: actions/configure-pages@v4 + + - name: Build with Jekyll + working-directory: ./gh_pages + run: bundle exec jekyll build --baseurl "${{ steps.pages.outputs.base_path }}" + env: + JEKYLL_ENV: production + + - name: Upload artifact + uses: actions/upload-pages-artifact@v3 + with: + path: ./gh_pages/_site + + deploy: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + needs: build + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 diff --git a/README.md b/README.md index e771f51..1774e1c 100644 --- a/README.md +++ b/README.md @@ -2,13 +2,11 @@ This repository includes both the source files and the release package for the TwinCAT Event Video Playback package. The package provides an easy to use PLC interface for assembling images captured with TwinCAT Vision into a single video file. When the video file is created, a corresponding alarm event is logged into the TwinCAT Event Logger for later viewing. In addition, an HMI Control component is supplied for easy viewing and playback of logged video events on TwinCAT HMI. +**WARNING: Remove any installs from the legacy TC_EventVideoPlayback before using the new 4026 version** + ## Quick Start -**For end users**: Instead of building from source, download the installer from the [Releases section](https://github.com/Beckhoff-USA-Community/EventVideoPlayback/releases). The release package includes: -- Sample PLC project -- Sample HMI project -- PLC library -- Windows service installer +**For end users**: Instead of building from source, connect to the [Beckhoff USA Communtiy package](https://packages.beckhoff-usa-community.com/) feed like you would normally with Beckhoff Official Packages. **For developers**: See [Building from Source](#building-from-source) below. diff --git a/docs/images/Camera-Alam-Icon-Color-Small.png b/docs/images/Camera-Alam-Icon-Color-Small.png deleted file mode 100644 index 4df7fe5..0000000 Binary files a/docs/images/Camera-Alam-Icon-Color-Small.png and /dev/null differ diff --git a/docs/images/Camera-Alam-Icon-Color.png b/docs/images/Camera-Alam-Icon-Color.png deleted file mode 100644 index 9402aee..0000000 Binary files a/docs/images/Camera-Alam-Icon-Color.png and /dev/null differ diff --git a/docs/images/Camera-Alarm-Icon.ico b/docs/images/Camera-Alarm-Icon.ico deleted file mode 100644 index 9bdb484..0000000 Binary files a/docs/images/Camera-Alarm-Icon.ico and /dev/null differ diff --git a/docs/images/Camera-Alarm-Icon.png b/docs/images/Camera-Alarm-Icon.png deleted file mode 100644 index 6c70cef..0000000 Binary files a/docs/images/Camera-Alarm-Icon.png and /dev/null differ diff --git a/docs/images/EventVideoPlayback.png b/docs/images/EventVideoPlayback.png deleted file mode 100644 index 355099c..0000000 Binary files a/docs/images/EventVideoPlayback.png and /dev/null differ diff --git a/docs/images/EventVideoPlayback_512x512.png b/docs/images/EventVideoPlayback_512x512.png deleted file mode 100644 index 992a363..0000000 Binary files a/docs/images/EventVideoPlayback_512x512.png and /dev/null differ diff --git a/docs/images/alarmIcon.png b/docs/images/alarmIcon.png deleted file mode 100644 index ce9adf9..0000000 Binary files a/docs/images/alarmIcon.png and /dev/null differ diff --git a/gh_pages/DEPLOYMENT.md b/gh_pages/DEPLOYMENT.md new file mode 100644 index 0000000..f0138bc --- /dev/null +++ b/gh_pages/DEPLOYMENT.md @@ -0,0 +1,325 @@ +# GitHub Pages Deployment Guide + +This guide explains how to deploy the Event Video Playback website to GitHub Pages. + +## Prerequisites + +Before deploying, ensure you have: +- Push access to the repository +- GitHub Pages enabled in repository settings + +## Deployment Methods + +### Method 1: Automatic Deployment (Recommended) + +The site automatically deploys when you push changes to the `main` or `v2.0.0` branches. + +1. **Make your changes** in the `gh_pages/` directory +2. **Commit your changes**: + ```bash + git add gh_pages/ + git commit -m "Update website content" + ``` +3. **Push to GitHub**: + ```bash + git push origin main + # or + git push origin v2.0.0 + ``` +4. **Monitor deployment**: + - Go to the repository **Actions** tab + - Watch the "Deploy Jekyll site to GitHub Pages" workflow + - Deployment typically takes 1-2 minutes + +5. **View the live site**: + - https://beckhoff-usa-community.github.io/EventVideoPlayback/ + +### Method 2: Manual Workflow Trigger + +You can manually trigger a deployment from the GitHub Actions interface: + +1. Go to the repository **Actions** tab +2. Select "Deploy Jekyll site to GitHub Pages" +3. Click "Run workflow" +4. Choose the branch (main or v2.0.0) +5. Click "Run workflow" button + +## First-Time Setup + +If this is the first deployment, you need to configure GitHub Pages settings: + +### Step 1: Enable GitHub Pages + +1. Go to repository **Settings** > **Pages** +2. Under "Build and deployment": + - **Source**: Deploy from a branch (this will be changed automatically) + - Or select: **GitHub Actions** (recommended) + +### Step 2: Set Permissions + +1. Go to repository **Settings** > **Actions** > **General** +2. Scroll to "Workflow permissions" +3. Select: **Read and write permissions** +4. Check: **Allow GitHub Actions to create and approve pull requests** +5. Click **Save** + +### Step 3: Configure Environment + +1. Go to repository **Settings** > **Environments** +2. You should see a "github-pages" environment +3. If not, it will be created automatically on first deployment + +### Step 4: First Deployment + +1. Push any change to trigger deployment: + ```bash + git add gh_pages/ + git commit -m "Initial website deployment" + git push origin main + ``` + +2. Go to **Actions** tab and watch the workflow +3. Wait for deployment to complete +4. The site URL will appear in the workflow output + +## Verifying Deployment + +### Check Workflow Status + +1. **Actions Tab**: View real-time build logs +2. **Green checkmark**: Deployment successful +3. **Red X**: Deployment failed (check logs for errors) + +### Test the Live Site + +Visit: https://beckhoff-usa-community.github.io/EventVideoPlayback/ + +**Test checklist:** +- [ ] Landing page loads correctly +- [ ] Hero image displays +- [ ] Navigation menu works +- [ ] All documentation pages load +- [ ] Internal links work +- [ ] Styles and colors are correct +- [ ] Mobile responsive design works +- [ ] JavaScript animations work + +## Troubleshooting + +### Deployment Fails + +**Error: "Process completed with exit code 16"** +- Jekyll build failed +- Check syntax in Markdown files +- Verify YAML front matter is correct +- Review GitHub Actions logs for specific errors + +**Fix:** +```bash +# Test build locally +cd gh_pages +bundle exec jekyll build +# Fix any errors shown +``` + +**Error: "No uploaded artifact was found"** +- Build completed but artifact upload failed +- Usually temporary; retry deployment + +**Fix:** +- Re-run the workflow from Actions tab +- Check GitHub status page for outages + +### Site Not Updating + +**Changes not visible after deployment:** + +1. **Wait**: CDN propagation can take 1-2 minutes +2. **Clear cache**: + - Hard refresh: `Ctrl+Shift+R` (Windows) or `Cmd+Shift+R` (Mac) + - Open in private/incognito window +3. **Verify deployment**: + - Check Actions tab shows successful deployment + - Verify commit SHA matches latest push + +### 404 Errors on Navigation + +**Internal links showing 404:** + +1. Check `_config.yml` baseurl is correct: + ```yaml + baseurl: "/EventVideoPlayback" + ``` + +2. Verify links use `relative_url` filter: + ```liquid + {{ '/docs/getting-started/' | relative_url }} + ``` + +3. Check permalinks in front matter match navigation links + +### Styles Not Loading + +**CSS not applied:** + +1. Check `assets/css/style.scss` has front matter: + ```yaml + --- + --- + ``` + +2. Verify SCSS files are imported: + ```scss + @import "variables"; + @import "layout"; + @import "components"; + ``` + +3. Clear browser cache and try again + +### Images Not Loading + +**Hero image or other images broken:** + +1. Verify image path: + ```liquid + {{ '/assets/images/Camera_Hero_NoBackground.png' | relative_url }} + ``` + +2. Check image exists in `assets/images/` +3. Verify image filename matches (case-sensitive) + +## Workflow Details + +The deployment workflow (`.github/workflows/pages.yml`) performs these steps: + +1. **Checkout**: Gets the repository code +2. **Setup Ruby**: Installs Ruby 3.1 and dependencies +3. **Setup Pages**: Configures GitHub Pages +4. **Build Jekyll**: Compiles the site with production settings +5. **Upload Artifact**: Packages the built site +6. **Deploy**: Publishes to GitHub Pages + +### Workflow Triggers + +The workflow runs when: +- Pushing to `main` or `v2.0.0` branches +- Only if files in `gh_pages/` or workflow file change +- Manually triggered via Actions tab + +### Build Time + +Typical build and deployment: **1-2 minutes** + +Breakdown: +- Checkout: 5-10 seconds +- Ruby setup: 20-30 seconds +- Jekyll build: 15-30 seconds +- Deploy: 30-60 seconds + +## Making Changes Safely + +### Best Practices + +1. **Test Locally First**: + ```bash + cd gh_pages + bundle exec jekyll serve + # Test at http://localhost:4000/EventVideoPlayback/ + ``` + +2. **Use Feature Branches**: + ```bash + git checkout -b update-documentation + # Make changes + git commit -m "Update documentation" + git push origin update-documentation + # Create pull request for review + ``` + +3. **Review Before Merge**: + - Check pull request preview + - Verify changes in GitHub's file view + - Review with team if needed + +4. **Monitor Deployment**: + - Watch Actions tab after merge + - Test live site immediately after deployment + - Be ready to rollback if issues occur + +### Emergency Rollback + +If a deployment breaks the site: + +1. **Revert the commit**: + ```bash + git revert HEAD + git push origin main + ``` + +2. **Or reset to previous version**: + ```bash + git reset --hard + git push origin main --force + ``` + +3. **Or checkout previous version**: + ```bash + git checkout gh_pages/ + git commit -m "Rollback to previous version" + git push origin main + ``` + +## Performance Optimization + +### Image Optimization + +Before adding images: +```bash +# Optimize PNG +optipng -o7 assets/images/image.png + +# Or use ImageMagick +convert input.png -strip -quality 85 output.png +``` + +### Build Optimization + +The workflow uses: +- Bundler cache for faster Ruby setup +- Incremental builds (when possible) +- Production environment for optimized output + +## Monitoring + +### GitHub Pages Status + +Check: https://www.githubstatus.com/ + +Look for issues with: +- GitHub Pages +- GitHub Actions +- Git Operations + +### Site Analytics + +Consider adding: +- Google Analytics +- GitHub Traffic Stats (Settings > Insights > Traffic) + +## Support + +**Issues with deployment?** + +1. Check [GitHub Actions logs](../../actions) +2. Review [GitHub Pages documentation](https://docs.github.com/en/pages) +3. Check [Jekyll documentation](https://jekyllrb.com/docs/) +4. Open an issue in the repository + +## Additional Resources + +- [GitHub Pages Documentation](https://docs.github.com/en/pages) +- [Jekyll Documentation](https://jekyllrb.com/docs/) +- [GitHub Actions Documentation](https://docs.github.com/en/actions) +- [Repository Settings](../../settings) +- [View Deployments](../../deployments/github-pages) diff --git a/gh_pages/Event Video Playback Configuration.md b/gh_pages/Event Video Playback Configuration.md new file mode 100644 index 0000000..22a7a9c --- /dev/null +++ b/gh_pages/Event Video Playback Configuration.md @@ -0,0 +1,82 @@ + +# Event Video Playback Configuration + + + +## EventVideoPlayback Service Configuration + +The EventVideoPlayback Service controls the creation of the video and automatic deletion of video files based on video age and folder max size + +The EventVideoPlayback Service reads the configuration file on startup. You must restart the service for changes to take effect. A reboot will also work. To stop and start the service, open the Windows Services window -> Right-click the EventVideoPlayback service and choose Stop or Start. + +The config file is located at```C:\Program Files\Beckhoff USA Community\EventVideoPlayback\Service\EventVideoPlaybackService.config.json``` + +Open the file with notepad or Visual Studio and you will see the following parameters + +```json +{ + "CodecFourCC": "avc1", + "VideoDeleteTime": 1, + "AdsPort": 26129, + "MaxFolderSize": 250 +} +``` + +#### CodecFourCC + +This is the codec used to create the video from the service. avc1 is the most common codec that is also compatible with web browsers. For a full list of codecs see below, but not all are web compatible and will display as a black box on Tc HMI. [Check here for appropriate codecs](https://developer.mozilla.org/en-US/docs/Web/Media/Formats/Video_codecs). + +``` +OpenCV: FFMPEG: format mp4 / MP4 (MPEG-4 Part 14) +fourcc tag 0x7634706d/'mp4v' codec_id 000C +fourcc tag 0x31637661/'avc1' codec_id 001B +fourcc tag 0x33637661/'avc3' codec_id 001B +fourcc tag 0x31766568/'hev1' codec_id 00AD +fourcc tag 0x31637668/'hvc1' codec_id 00AD +fourcc tag 0x7634706d/'mp4v' codec_id 0002 +fourcc tag 0x7634706d/'mp4v' codec_id 0001 +fourcc tag 0x7634706d/'mp4v' codec_id 0007 +fourcc tag 0x7634706d/'mp4v' codec_id 003D +fourcc tag 0x7634706d/'mp4v' codec_id 0058 +fourcc tag 0x312d6376/'vc-1' codec_id 0046 +fourcc tag 0x63617264/'drac' codec_id 0074 +fourcc tag 0x7634706d/'mp4v' codec_id 00A3 +fourcc tag 0x39307076/'vp09' codec_id 00A7 +fourcc tag 0x31307661/'av01' codec_id 801D +fourcc tag 0x6134706d/'mp4a' codec_id 15002 +fourcc tag 0x63616c61/'alac' codec_id 15010 +fourcc tag 0x6134706d/'mp4a' codec_id 1502D +fourcc tag 0x6134706d/'mp4a' codec_id 15001 +fourcc tag 0x6134706d/'mp4a' codec_id 15000 +fourcc tag 0x332d6361/'ac-3' codec_id 15003 +fourcc tag 0x332d6365/'ec-3' codec_id 15028 +fourcc tag 0x6134706d/'mp4a' codec_id 15004 +fourcc tag 0x61706c6d/'mlpa' codec_id 1502C +fourcc tag 0x43614c66/'fLaC' codec_id 1500C +fourcc tag 0x7375704f/'Opus' codec_id 1503C +fourcc tag 0x6134706d/'mp4a' codec_id 15005 +fourcc tag 0x6134706d/'mp4a' codec_id 15018 +fourcc tag 0x6134706d/'mp4a' codec_id 15803 +fourcc tag 0x7334706d/'mp4s' codec_id 17000 +fourcc tag 0x67337874/'tx3g' codec_id 17005 +fourcc tag 0x646d7067/'gpmd' codec_id 18807 +fourcc tag 0x316d686d/'mhm1' codec_id 15817 +``` + +#### VideoDeleteTime + +This is the amount of time that the file will stay stored on the system. If the time expired, the service will automatically cleanup old video files. + +The value is a floating point value, and is in units of Days. So for half a day you will need to put 0.5 as the value. + +#### AdsPort + +Do not change. This is the ADS Port that the service is hosting on. This should remain at port 26129 at all times in order for the PLC function blocks to work properly. + +#### MaxFolderSize + +This is the Max size of the folder holding videos. When a new video is created, the folder size is checked and the oldest video will be deleted if required. + +The value is a integer point value, and is in units of MB. + +#### diff --git a/gh_pages/Gemfile b/gh_pages/Gemfile new file mode 100644 index 0000000..f164f8c --- /dev/null +++ b/gh_pages/Gemfile @@ -0,0 +1,9 @@ +source "https://rubygems.org" + +gem "github-pages", group: :jekyll_plugins +gem "webrick" # Required for Ruby 3.0+ + +group :jekyll_plugins do + gem "jekyll-seo-tag" + gem "jekyll-sitemap" +end diff --git a/gh_pages/Gemfile.lock b/gh_pages/Gemfile.lock new file mode 100644 index 0000000..38f15cb --- /dev/null +++ b/gh_pages/Gemfile.lock @@ -0,0 +1,287 @@ +GEM + remote: https://rubygems.org/ + specs: + activesupport (8.1.1) + base64 + bigdecimal + concurrent-ruby (~> 1.0, >= 1.3.1) + connection_pool (>= 2.2.5) + drb + i18n (>= 1.6, < 2) + json + logger (>= 1.4.2) + minitest (>= 5.1) + securerandom (>= 0.3) + tzinfo (~> 2.0, >= 2.0.5) + uri (>= 0.13.1) + addressable (2.8.7) + public_suffix (>= 2.0.2, < 7.0) + base64 (0.3.0) + bigdecimal (3.3.1) + coffee-script (2.4.1) + coffee-script-source + execjs + coffee-script-source (1.12.2) + colorator (1.1.0) + commonmarker (0.23.12) + concurrent-ruby (1.3.5) + connection_pool (2.5.4) + csv (3.3.5) + dnsruby (1.73.1) + base64 (>= 0.2) + logger (~> 1.6) + simpleidn (~> 0.2.1) + drb (2.2.3) + em-websocket (0.5.3) + eventmachine (>= 0.12.9) + http_parser.rb (~> 0) + ethon (0.15.0) + ffi (>= 1.15.0) + eventmachine (1.2.7) + execjs (2.10.0) + faraday (2.14.0) + faraday-net_http (>= 2.0, < 3.5) + json + logger + faraday-net_http (3.4.2) + net-http (~> 0.5) + ffi (1.17.2-x64-mingw-ucrt) + ffi (1.17.2-x86_64-linux-gnu) + forwardable-extended (2.6.0) + gemoji (4.1.0) + github-pages (232) + github-pages-health-check (= 1.18.2) + jekyll (= 3.10.0) + jekyll-avatar (= 0.8.0) + jekyll-coffeescript (= 1.2.2) + jekyll-commonmark-ghpages (= 0.5.1) + jekyll-default-layout (= 0.1.5) + jekyll-feed (= 0.17.0) + jekyll-gist (= 1.5.0) + jekyll-github-metadata (= 2.16.1) + jekyll-include-cache (= 0.2.1) + jekyll-mentions (= 1.6.0) + jekyll-optional-front-matter (= 0.3.2) + jekyll-paginate (= 1.1.0) + jekyll-readme-index (= 0.3.0) + jekyll-redirect-from (= 0.16.0) + jekyll-relative-links (= 0.6.1) + jekyll-remote-theme (= 0.4.3) + jekyll-sass-converter (= 1.5.2) + jekyll-seo-tag (= 2.8.0) + jekyll-sitemap (= 1.4.0) + jekyll-swiss (= 1.0.0) + jekyll-theme-architect (= 0.2.0) + jekyll-theme-cayman (= 0.2.0) + jekyll-theme-dinky (= 0.2.0) + jekyll-theme-hacker (= 0.2.0) + jekyll-theme-leap-day (= 0.2.0) + jekyll-theme-merlot (= 0.2.0) + jekyll-theme-midnight (= 0.2.0) + jekyll-theme-minimal (= 0.2.0) + jekyll-theme-modernist (= 0.2.0) + jekyll-theme-primer (= 0.6.0) + jekyll-theme-slate (= 0.2.0) + jekyll-theme-tactile (= 0.2.0) + jekyll-theme-time-machine (= 0.2.0) + jekyll-titles-from-headings (= 0.5.3) + jemoji (= 0.13.0) + kramdown (= 2.4.0) + kramdown-parser-gfm (= 1.1.0) + liquid (= 4.0.4) + mercenary (~> 0.3) + minima (= 2.5.1) + nokogiri (>= 1.16.2, < 2.0) + rouge (= 3.30.0) + terminal-table (~> 1.4) + webrick (~> 1.8) + github-pages-health-check (1.18.2) + addressable (~> 2.3) + dnsruby (~> 1.60) + octokit (>= 4, < 8) + public_suffix (>= 3.0, < 6.0) + typhoeus (~> 1.3) + html-pipeline (2.14.3) + activesupport (>= 2) + nokogiri (>= 1.4) + http_parser.rb (0.8.0) + i18n (1.14.7) + concurrent-ruby (~> 1.0) + jekyll (3.10.0) + addressable (~> 2.4) + colorator (~> 1.0) + csv (~> 3.0) + em-websocket (~> 0.5) + i18n (>= 0.7, < 2) + jekyll-sass-converter (~> 1.0) + jekyll-watch (~> 2.0) + kramdown (>= 1.17, < 3) + liquid (~> 4.0) + mercenary (~> 0.3.3) + pathutil (~> 0.9) + rouge (>= 1.7, < 4) + safe_yaml (~> 1.0) + webrick (>= 1.0) + jekyll-avatar (0.8.0) + jekyll (>= 3.0, < 5.0) + jekyll-coffeescript (1.2.2) + coffee-script (~> 2.2) + coffee-script-source (~> 1.12) + jekyll-commonmark (1.4.0) + commonmarker (~> 0.22) + jekyll-commonmark-ghpages (0.5.1) + commonmarker (>= 0.23.7, < 1.1.0) + jekyll (>= 3.9, < 4.0) + jekyll-commonmark (~> 1.4.0) + rouge (>= 2.0, < 5.0) + jekyll-default-layout (0.1.5) + jekyll (>= 3.0, < 5.0) + jekyll-feed (0.17.0) + jekyll (>= 3.7, < 5.0) + jekyll-gist (1.5.0) + octokit (~> 4.2) + jekyll-github-metadata (2.16.1) + jekyll (>= 3.4, < 5.0) + octokit (>= 4, < 7, != 4.4.0) + jekyll-include-cache (0.2.1) + jekyll (>= 3.7, < 5.0) + jekyll-mentions (1.6.0) + html-pipeline (~> 2.3) + jekyll (>= 3.7, < 5.0) + jekyll-optional-front-matter (0.3.2) + jekyll (>= 3.0, < 5.0) + jekyll-paginate (1.1.0) + jekyll-readme-index (0.3.0) + jekyll (>= 3.0, < 5.0) + jekyll-redirect-from (0.16.0) + jekyll (>= 3.3, < 5.0) + jekyll-relative-links (0.6.1) + jekyll (>= 3.3, < 5.0) + jekyll-remote-theme (0.4.3) + addressable (~> 2.0) + jekyll (>= 3.5, < 5.0) + jekyll-sass-converter (>= 1.0, <= 3.0.0, != 2.0.0) + rubyzip (>= 1.3.0, < 3.0) + jekyll-sass-converter (1.5.2) + sass (~> 3.4) + jekyll-seo-tag (2.8.0) + jekyll (>= 3.8, < 5.0) + jekyll-sitemap (1.4.0) + jekyll (>= 3.7, < 5.0) + jekyll-swiss (1.0.0) + jekyll-theme-architect (0.2.0) + jekyll (> 3.5, < 5.0) + jekyll-seo-tag (~> 2.0) + jekyll-theme-cayman (0.2.0) + jekyll (> 3.5, < 5.0) + jekyll-seo-tag (~> 2.0) + jekyll-theme-dinky (0.2.0) + jekyll (> 3.5, < 5.0) + jekyll-seo-tag (~> 2.0) + jekyll-theme-hacker (0.2.0) + jekyll (> 3.5, < 5.0) + jekyll-seo-tag (~> 2.0) + jekyll-theme-leap-day (0.2.0) + jekyll (> 3.5, < 5.0) + jekyll-seo-tag (~> 2.0) + jekyll-theme-merlot (0.2.0) + jekyll (> 3.5, < 5.0) + jekyll-seo-tag (~> 2.0) + jekyll-theme-midnight (0.2.0) + jekyll (> 3.5, < 5.0) + jekyll-seo-tag (~> 2.0) + jekyll-theme-minimal (0.2.0) + jekyll (> 3.5, < 5.0) + jekyll-seo-tag (~> 2.0) + jekyll-theme-modernist (0.2.0) + jekyll (> 3.5, < 5.0) + jekyll-seo-tag (~> 2.0) + jekyll-theme-primer (0.6.0) + jekyll (> 3.5, < 5.0) + jekyll-github-metadata (~> 2.9) + jekyll-seo-tag (~> 2.0) + jekyll-theme-slate (0.2.0) + jekyll (> 3.5, < 5.0) + jekyll-seo-tag (~> 2.0) + jekyll-theme-tactile (0.2.0) + jekyll (> 3.5, < 5.0) + jekyll-seo-tag (~> 2.0) + jekyll-theme-time-machine (0.2.0) + jekyll (> 3.5, < 5.0) + jekyll-seo-tag (~> 2.0) + jekyll-titles-from-headings (0.5.3) + jekyll (>= 3.3, < 5.0) + jekyll-watch (2.2.1) + listen (~> 3.0) + jemoji (0.13.0) + gemoji (>= 3, < 5) + html-pipeline (~> 2.2) + jekyll (>= 3.0, < 5.0) + json (2.16.0) + kramdown (2.4.0) + rexml + kramdown-parser-gfm (1.1.0) + kramdown (~> 2.0) + liquid (4.0.4) + listen (3.9.0) + rb-fsevent (~> 0.10, >= 0.10.3) + rb-inotify (~> 0.9, >= 0.9.10) + logger (1.7.0) + mercenary (0.3.6) + minima (2.5.1) + jekyll (>= 3.5, < 5.0) + jekyll-feed (~> 0.9) + jekyll-seo-tag (~> 2.1) + minitest (5.26.1) + net-http (0.7.0) + uri + nokogiri (1.18.10-x64-mingw-ucrt) + racc (~> 1.4) + nokogiri (1.18.10-x86_64-linux-gnu) + racc (~> 1.4) + octokit (4.25.1) + faraday (>= 1, < 3) + sawyer (~> 0.9) + pathutil (0.16.2) + forwardable-extended (~> 2.6) + public_suffix (5.1.1) + racc (1.8.1) + rb-fsevent (0.11.2) + rb-inotify (0.11.1) + ffi (~> 1.0) + rexml (3.4.4) + rouge (3.30.0) + rubyzip (2.4.1) + safe_yaml (1.0.5) + sass (3.7.4) + sass-listen (~> 4.0.0) + sass-listen (4.0.0) + rb-fsevent (~> 0.9, >= 0.9.4) + rb-inotify (~> 0.9, >= 0.9.7) + sawyer (0.9.3) + addressable (>= 2.3.5) + faraday (>= 0.17.3, < 3) + securerandom (0.4.1) + simpleidn (0.2.3) + terminal-table (1.8.0) + unicode-display_width (~> 1.1, >= 1.1.1) + typhoeus (1.5.0) + ethon (>= 0.9.0, < 0.16.0) + tzinfo (2.0.6) + concurrent-ruby (~> 1.0) + unicode-display_width (1.8.0) + uri (1.1.1) + webrick (1.9.1) + +PLATFORMS + x64-mingw-ucrt + x86_64-linux + +DEPENDENCIES + github-pages + jekyll-seo-tag + jekyll-sitemap + webrick + +BUNDLED WITH + 2.7.2 diff --git a/gh_pages/README.md b/gh_pages/README.md new file mode 100644 index 0000000..7866949 --- /dev/null +++ b/gh_pages/README.md @@ -0,0 +1,216 @@ +# Event Video Playback - GitHub Pages Website + +This directory contains the Jekyll-based GitHub Pages website for the Event Video Playback project. + +## 🚀 Quick Start + +### Local Development + +1. **Install Ruby and Jekyll** (if not already installed): + - Windows: Use [RubyInstaller](https://rubyinstaller.org/) + - macOS: `brew install ruby` + - Linux: `sudo apt-get install ruby-full` + +2. **Install dependencies**: + ```bash + cd gh_pages + bundle install + ``` + +3. **Run the local server**: + ```bash + bundle exec jekyll serve + ``` + +4. **View the site**: + Open http://localhost:4000/EventVideoPlayback/ in your browser + +### Automatic Deployment + +The site automatically deploys to GitHub Pages when you push changes to the `main` or `v2.0.0` branches. The deployment is handled by the GitHub Actions workflow at `.github/workflows/pages.yml`. + +**Live Site**: https://beckhoff-usa-community.github.io/EventVideoPlayback/ + +## 📁 Directory Structure + +``` +gh_pages/ +├── _config.yml # Jekyll configuration +├── Gemfile # Ruby dependencies +├── index.md # Landing page (hero section) +├── _layouts/ # Page layouts +│ ├── default.html # Base layout with header/footer +│ ├── home.html # Landing page layout +│ └── doc.html # Documentation page layout +├── _includes/ # Reusable components +│ ├── header.html # Site header with navigation +│ └── footer.html # Site footer +├── _docs/ # Documentation pages +│ ├── getting-started.md # Installation guide +│ ├── plc-usage.md # PLC library documentation +│ ├── service-config.md # Service configuration guide +│ └── hmi-usage.md # HMI NuGet package guide +├── _sass/ # SCSS stylesheets +│ ├── _variables.scss # Color scheme and design tokens +│ ├── _layout.scss # Layout styles +│ └── _components.scss # Component styles (hero, cards, etc.) +├── assets/ +│ ├── css/ +│ │ └── style.scss # Main stylesheet (imports all SCSS) +│ ├── js/ +│ │ └── main.js # JavaScript for interactions +│ └── images/ +│ └── Camera_Hero_NoBackground.png # Hero image +└── README.md # This file +``` + +## 🎨 Design System + +### Color Palette + +- **Primary Red**: `#D32F2F` +- **Dark Red**: `#C62828` +- **Accent Red**: `#FF5252` +- **Black**: `#1a1a1a` +- **Dark Gray**: `#212121` +- **Light Gray**: `#F5F5F5` +- **White**: `#FFFFFF` + +### Typography + +- **Font**: Inter (from Google Fonts) +- **Base Size**: 16px +- **Line Height**: 1.6 + +### Breakpoints + +- **Mobile**: 480px +- **Tablet**: 768px +- **Desktop**: 1024px +- **Wide**: 1280px + +## 📝 Updating Content + +### Modifying the Landing Page + +Edit `index.md` to change: +- Hero section text and buttons +- Feature cards +- Overview section +- System requirements +- Call-to-action sections + +### Updating Documentation + +Documentation pages are in the `_docs/` directory: + +1. **Getting Started** (`_docs/getting-started.md`): Installation and setup +2. **PLC Library Usage** (`_docs/plc-usage.md`): Function blocks and examples +3. **Service Configuration** (`_docs/service-config.md`): Windows service settings +4. **HMI Usage** (`_docs/hmi-usage.md`): WPF control integration + +Each documentation page uses the `doc` layout and includes: +```yaml +--- +layout: doc +title: Page Title +description: Brief description +permalink: /docs/page-name/ +--- +``` + +### Adding New Pages + +1. Create a new Markdown file in `_docs/` +2. Add front matter with layout, title, description, and permalink +3. Add the page to `_config.yml` under `header_pages` +4. Update navigation in `_includes/header.html` if needed + +## 🎯 Customization + +### Changing Colors + +Edit `_sass/_variables.scss` to modify the color scheme: + +```scss +$primary-red: #D32F2F; // Your primary color +$dark-red: #C62828; // Darker variant +$accent-red: #FF5252; // Accent color +``` + +### Modifying Styles + +- **Layout styles**: `_sass/_layout.scss` +- **Component styles**: `_sass/_components.scss` +- **Variables**: `_sass/_variables.scss` + +### Adding JavaScript + +Edit `assets/js/main.js` to add interactive features. + +## 🔧 Configuration + +Key settings in `_config.yml`: + +```yaml +title: Event Video Playback +description: Transform TwinCAT Vision images into event-driven video recordings +baseurl: "/EventVideoPlayback" +url: "https://beckhoff-usa-community.github.io" +``` + +## 🚨 Troubleshooting + +### Site not updating after push + +1. Check GitHub Actions status in the **Actions** tab +2. Verify the workflow ran successfully +3. Wait 1-2 minutes for changes to propagate +4. Clear browser cache and refresh + +### Styles not loading + +1. Ensure `assets/css/style.scss` has front matter (`---` at the top) +2. Check that SCSS files in `_sass/` are properly imported +3. Verify file paths are correct + +### Navigation links broken + +1. Check `_config.yml` for correct `baseurl` +2. Use Liquid tags for links: `{{ '/docs/page/' | relative_url }}` +3. Ensure permalink in front matter matches navigation links + +### Local build fails + +```bash +# Clear Jekyll cache +bundle exec jekyll clean + +# Reinstall dependencies +bundle install + +# Try building again +bundle exec jekyll serve +``` + +## 📚 Resources + +- [Jekyll Documentation](https://jekyllrb.com/docs/) +- [GitHub Pages Documentation](https://docs.github.com/en/pages) +- [Liquid Template Language](https://shopify.github.io/liquid/) +- [Markdown Guide](https://www.markdownguide.org/) + +## 🤝 Contributing + +When updating the website: + +1. Test changes locally first with `bundle exec jekyll serve` +2. Check responsive design on mobile, tablet, and desktop +3. Verify all links work +4. Ensure images load correctly +5. Test navigation between pages +6. Push to a branch and create a pull request + +## 📄 License + +This website content is part of the Event Video Playback project and is licensed under the MIT License. See the [LICENSE](../LICENSE) file in the repository root. diff --git a/gh_pages/_config.yml b/gh_pages/_config.yml new file mode 100644 index 0000000..b4e3d87 --- /dev/null +++ b/gh_pages/_config.yml @@ -0,0 +1,34 @@ +title: Event Video Playback +description: Transform TwinCAT Vision images into event-driven video recordings +baseurl: "/EventVideoPlayback" +url: "https://beckhoff-usa-community.github.io" + +# Build settings +theme: minima +plugins: + - jekyll-seo-tag + - jekyll-sitemap + +# Collections for documentation +collections: + docs: + output: true + permalink: /docs/:path/ + +# Navigation +header_pages: + - _docs/getting-started.md + - _docs/plc-usage.md + - _docs/service-config.md + - _docs/hmi-usage.md + +# Exclude from processing +exclude: + - Gemfile + - Gemfile.lock + - node_modules + - vendor/bundle/ + - vendor/cache/ + - vendor/gems/ + - vendor/ruby/ + - instruction.md diff --git a/gh_pages/_docs/getting-started.md b/gh_pages/_docs/getting-started.md new file mode 100644 index 0000000..d00559e --- /dev/null +++ b/gh_pages/_docs/getting-started.md @@ -0,0 +1,162 @@ +--- +layout: doc +title: Getting Started +description: Learn how to install and configure Event Video Playback for your TwinCAT project +permalink: /docs/getting-started/ +--- +## Overview + +Event Video Playback is a comprehensive solution for transforming TwinCAT Vision images into event-driven video recordings. This guide will walk you through the installation and initial setup process. + +## Prerequisites + +Before you begin, ensure you have the following installed on your system: + +For Engineering Development: +- **Windows 10/11** +- **TwinCAT Package Manager** +- **TwinCAT 3.1 XAE** Build 4026 or higher +- **TwinCAT Vision XAE** 5.8.4 or higher +- **TwinCAT HMI XAE** 14.9 or higher + +For Runtime Targets: +- **Windows 10/11** +- **TwinCAT Package Manager** +- **TwinCAT 3.1 XAR** Build 4026 or higher +- **TwinCAT Vision XAR** 5.8.4 or higher + +
+Warning: Previous versions of the 4024 Tc_EventVideoPlayback legacy project must be uninstalled before using the new 4026 build. +
+ +### TcPkg Package Signing Requirement + +TwinCAT Package Manager only accepts officially signed packages from Beckhoff Automation GmbH & Co. KG by default. To use community packages, you need to temporarily disable signature verification. This applies to both locally hosted packages and remote packages; any 3rd party developed packages. + +
+ Security Notice: Disabling signature verification allows installation of third-party packages. Only use packages from trusted community sources. Review package contents and source code before installation. All community packages are provided "as is" without warranties. +
+ +Run this command in PowerShell as Administrator to disable signature checks: +```PowerShell +tcpkg config unset -n VerifySignatures +``` + +## Installation Methods + +Choose the installation method that best fits your environment: + +- **[Online Installation](#online-installation)** - For systems with internet access (recommended) +- **[Offline Installation](#offline-installation)** - For air-gapped systems or manual installation + +--- + +## Online Package Feed Connection + +**Best for:** Systems with internet connectivity and access to the Beckhoff USA Community package feed. + +### Add Package Feed via GUI + +If you haven't already, add the Beckhoff USA Community package feed to TwinCAT Package Manager: + +1. Open the TwinCAT Package Manager GUI +2. Click the Settings (Gear Icon) in the bottom left corner +3. Select Feeds + +For the feed settings use: +```bash +https://packages.beckhoff-usa-community.com/stable/v3/index.json +``` +For the feed name use: +```bash +Beckhoff USA Community Stable +``` +Deselect the **Set credentials** option, as we do not need login for the feed. Select **Save** and agree to the disclaimer to be connected. + +### Add Package Feed via Powershell + +```bash +tcpkg source add -n "Beckhoff USA Community Stable" -s "https://packages.beckhoff-usa-community.com/stable/v3/index.json" +``` +Agree to the disclaimer to be connected. + +--- + +## Offline Package Configuration + +**Best for:** Air-gapped systems, manual installations, or when you need a specific version. + +
+ Tip: Instead of downloading the packages from the releases section as noted below, you can also use the PowerShell command tcpkg download [package name] -o [output location] +
+ +### Download from GitHub Releases + +1. Navigate to the [GitHub Releases page](https://github.com/Beckhoff-USA-Community/EventVideoPlayback/releases) +2. Find the latest release (or the version you need) +3. Download the package file (`.zip`) +4. Transfer the files to your target system in an easy to remember location (Example: C:\Program Files\Beckhoff USA Community\Feeds\Local) + +### Add Local Package Feed via GUI + +If you haven't already, add the Beckhoff USA Community package feed to TwinCAT Package Manager: + +1. Open the TwinCAT Package Manager GUI +2. Click the Settings (Gear Icon) in the bottom left corner +3. Select Feeds + +For the feed settings use: +```bash +C:\Program Files\Beckhoff USA Community\Feeds\Local +``` +For the feed name use: +```bash +Beckhoff USA Community Local +``` +Deselect the **Set credentials** option, as we do not need login for the feed. Select **Save**. + +### Add Package Feed via Powershell + +```bash +tcpkg source add -n "Beckhoff USA Community Local" -s "C:\Program Files\Beckhoff USA Community\Feeds\Local" +``` + +## Install Workloads + +After the feed is added (locally or remote), and the VerifySignatures is disabled, you can now install the Workloads and Packages on the feed like you would normal Beckhoff Automation packages. + + + +## Next Steps + +- Learn about [PLC Library Usage]({{ '/docs/plc-usage/' | relative_url }}) for advanced features +- Configure [Service Settings]({{ '/docs/service-config/' | relative_url }}) for your environment +- Add [HMI Controls]({{ '/docs/hmi-usage/' | relative_url }}) for video playback + +## Troubleshooting + +### Service Won't Start + +- Verify .NET 8 Runtime is installed +- Check Windows Event Viewer for error messages +- Ensure no other service is using ADS port 26129 + +### Videos Not Being Created + +- Confirm TwinCAT Vision is saving images to the configured path +- Check service configuration file for correct paths +- Verify sufficient disk space is available + +### PLC Function Block Errors + +- Ensure the library reference is added correctly +- Verify the service is running +- Check ADS communication settings + +## Support + +Need help? Here are some resources: + +- [GitHub Issues](https://github.com/Beckhoff-USA-Community/EventVideoPlayback/issues) - Report bugs or request features +- [Beckhoff USA Community](https://github.com/Beckhoff-USA-Community) - Community support and discussions +- [Documentation]({{ '/' | relative_url }}) - Additional guides and references \ No newline at end of file diff --git a/gh_pages/_docs/hmi-usage.md b/gh_pages/_docs/hmi-usage.md new file mode 100644 index 0000000..68085e3 --- /dev/null +++ b/gh_pages/_docs/hmi-usage.md @@ -0,0 +1,458 @@ +--- +layout: doc +title: HMI NuGet Package Usage +description: Integrate video playback controls into your TwinCAT HMI and WPF applications +permalink: /docs/hmi-usage/ +--- + +## Overview + +The Event Video Playback HMI NuGet package provides ready-to-use WPF controls for displaying and controlling video playback in your HMI applications. This guide covers installation, configuration, and usage. + +## Installation + +### Prerequisites + +- **Visual Studio 2019 or later** +- **TwinCAT HMI Framework** (for HMI projects) or standalone **WPF application** +- **.NET 8 Framework** +- **NuGet Package Manager** + +### Install via NuGet + +#### Option 1: Package Manager Console + +```powershell +Install-Package EventVideoPlayback.HMI +``` + +#### Option 2: NuGet Package Manager UI + +1. Right-click on your project in Solution Explorer +2. Select **Manage NuGet Packages** +3. Click on **Browse** tab +4. Search for "EventVideoPlayback.HMI" +5. Click **Install** + +#### Option 3: Beckhoff USA Community Package Feed + +Add the Beckhoff USA Community package feed to your NuGet sources: + +1. **Tools** > **Options** > **NuGet Package Manager** > **Package Sources** +2. Click the **+** button +3. Name: `Beckhoff USA Community` +4. Source: `https://packages.beckhoff-usa-community.com/nuget/v3/index.json` +5. Click **OK** + +Then search for and install the package. + +## Video Player Control + +### Basic Usage + +Add the video player control to your XAML: + +```xml + + + + + + +``` + +### Control Properties + +| Property | Type | Default | Description | +|----------|------|---------|-------------| +| `VideoSource` | string | null | Path to the video file to play | +| `AutoPlay` | bool | false | Automatically start playback when source is set | +| `ShowControls` | bool | true | Display playback controls | +| `Volume` | double | 0.5 | Volume level (0.0 to 1.0) | +| `IsMuted` | bool | false | Mute audio | +| `Loop` | bool | false | Loop video playback | +| `Stretch` | Stretch | Uniform | How video is stretched to fill control | + +### Control Methods + +```csharp +// Play the video +videoPlayer.Play(); + +// Pause the video +videoPlayer.Pause(); + +// Stop the video +videoPlayer.Stop(); + +// Seek to specific position (in seconds) +videoPlayer.Seek(10.5); + +// Load a new video +videoPlayer.LoadVideo("C:\\Videos\\MachineEvent_001.mp4"); + +// Take a snapshot +videoPlayer.SaveSnapshot("C:\\Snapshots\\snapshot.png"); +``` + +### Events + +```csharp +// Video loaded and ready to play +videoPlayer.VideoLoaded += (sender, e) => +{ + Debug.WriteLine($"Video loaded: {e.VideoPath}"); +}; + +// Playback started +videoPlayer.PlaybackStarted += (sender, e) => +{ + Debug.WriteLine("Playback started"); +}; + +// Playback paused +videoPlayer.PlaybackPaused += (sender, e) => +{ + Debug.WriteLine("Playback paused"); +}; + +// Playback completed +videoPlayer.PlaybackCompleted += (sender, e) => +{ + Debug.WriteLine("Playback completed"); +}; + +// Error occurred +videoPlayer.ErrorOccurred += (sender, e) => +{ + MessageBox.Show($"Error: {e.ErrorMessage}", "Video Error"); +}; +``` + +## Complete Example Application + +### XAML (MainWindow.xaml) + +```xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Home + Getting Started + PLC Library + Service Config + HMI Usage + GitHub + + + + diff --git a/gh_pages/_layouts/default.html b/gh_pages/_layouts/default.html new file mode 100644 index 0000000..f94944c --- /dev/null +++ b/gh_pages/_layouts/default.html @@ -0,0 +1,26 @@ + + + + + + + + {% if page.title %}{{ page.title }} | {% endif %}{{ site.title }} + + + + + {% seo %} + + + {% include header.html %} + +
+ {{ content }} +
+ + {% include footer.html %} + + + + diff --git a/gh_pages/_layouts/doc.html b/gh_pages/_layouts/doc.html new file mode 100644 index 0000000..ddca56e --- /dev/null +++ b/gh_pages/_layouts/doc.html @@ -0,0 +1,102 @@ +--- +layout: default +--- + +
+
+ + + +
+ + + + +
+
+ {% if page.title %} +

{{ page.title }}

+ {% endif %} + + {% if page.description %} +

{{ page.description }}

+ {% endif %} + + + {% assign pdf_name = "" %} + {% if page.permalink contains "getting-started" %} + {% assign pdf_name = "getting-started.pdf" %} + {% elsif page.permalink contains "plc-usage" %} + {% assign pdf_name = "plc-usage.pdf" %} + {% elsif page.permalink contains "service-config" %} + {% assign pdf_name = "service-config.pdf" %} + {% elsif page.permalink contains "hmi-usage" %} + {% assign pdf_name = "hmi-usage.pdf" %} + {% endif %} + + {% if pdf_name != "" %} + + {% endif %} + +
+ {{ content }} +
+ +
+ + +
+
+
+
+
+ + + diff --git a/gh_pages/_layouts/home.html b/gh_pages/_layouts/home.html new file mode 100644 index 0000000..5e71126 --- /dev/null +++ b/gh_pages/_layouts/home.html @@ -0,0 +1,5 @@ +--- +layout: default +--- + +{{ content }} diff --git a/gh_pages/_sass/_components.scss b/gh_pages/_sass/_components.scss new file mode 100644 index 0000000..8ec8748 --- /dev/null +++ b/gh_pages/_sass/_components.scss @@ -0,0 +1,856 @@ +// Hero Section +.hero { + position: relative; + min-height: 90vh; + display: flex; + align-items: center; + justify-content: center; + background: linear-gradient(135deg, $black 0%, $dark-gray 100%); + overflow: hidden; + text-align: center; + padding: $spacing-xxl $spacing-md; + + &::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: radial-gradient(circle at 30% 50%, rgba($primary-red, 0.15) 0%, transparent 50%); + pointer-events: none; + } + + .hero-content { + position: relative; + z-index: 2; + max-width: 1000px; + animation: fadeInUp 1s $transition-ease; + } + + .hero-image { + max-width: 500px; + width: 100%; + height: auto; + margin-bottom: $spacing-lg; + filter: drop-shadow(0 10px 30px rgba($primary-red, 0.3)); + animation: float 6s ease-in-out infinite; + + @media (max-width: $breakpoint-tablet) { + max-width: 300px; + } + } + + .hero-title { + font-size: 4rem; + color: $white; + margin-bottom: $spacing-sm; + font-weight: $font-weight-bold; + text-shadow: 0 4px 8px rgba(0, 0, 0, 0.3); + + @media (max-width: $breakpoint-tablet) { + font-size: 2.5rem; + } + } + + .hero-tagline { + font-size: 1.5rem; + color: $light-gray; + margin-bottom: $spacing-lg; + font-weight: $font-weight-light; + + @media (max-width: $breakpoint-tablet) { + font-size: 1.125rem; + } + } + + .hero-buttons { + display: flex; + gap: $spacing-sm; + justify-content: center; + flex-wrap: wrap; + } +} + +// Buttons +.btn { + display: inline-block; + padding: $spacing-sm $spacing-lg; + font-size: 1.125rem; + font-weight: $font-weight-medium; + text-decoration: none; + border-radius: $border-radius; + transition: all $transition-speed $transition-ease; + cursor: pointer; + border: 2px solid transparent; + text-align: center; + + &.btn-primary { + background: linear-gradient(135deg, $primary-red 0%, $dark-red 100%); + color: $white; + box-shadow: $shadow-lg; + + &:hover { + transform: translateY(-2px); + box-shadow: $shadow-xl; + background: linear-gradient(135deg, $dark-red 0%, $primary-red 100%); + } + + &:active { + transform: translateY(0); + } + } + + &.btn-secondary { + background-color: transparent; + color: $white; + border-color: $white; + + &:hover { + background-color: $white; + color: $primary-red; + transform: translateY(-2px); + } + } + + &.btn-ghost { + background-color: transparent; + color: $primary-red; + border-color: $primary-red; + + &:hover { + background-color: $primary-red; + color: $white; + } + } +} + +// Feature Cards +.features { + .features-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); + gap: $spacing-lg; + margin-top: $spacing-lg; + } +} + +.feature-card { + background-color: $white; + padding: $spacing-lg; + border-radius: $border-radius-lg; + box-shadow: $shadow-md; + transition: all $transition-speed $transition-ease; + border: 2px solid transparent; + + &:hover { + transform: translateY(-8px); + box-shadow: $shadow-xl; + border-color: $primary-red; + } + + .feature-icon { + font-size: 3rem; + color: $primary-red; + margin-bottom: $spacing-sm; + display: block; + } + + .feature-title { + font-size: $font-size-h3; + color: $dark-gray; + margin-bottom: $spacing-sm; + } + + .feature-description { + color: $medium-gray; + line-height: 1.7; + } +} + +// Section Headers +.section-header { + text-align: center; + margin-bottom: $spacing-xxl; + + .section-title { + font-size: $font-size-h2; + color: $dark-gray; + margin-bottom: $spacing-sm; + + .section-dark & { + color: $white; + } + } + + .section-subtitle { + font-size: 1.25rem; + color: $medium-gray; + font-weight: $font-weight-light; + max-width: 700px; + margin: 0 auto; + + .section-dark & { + color: $light-gray; + } + } +} + +// Overview Section +.overview { + display: grid; + grid-template-columns: 1fr 1fr; + gap: $spacing-xl; + align-items: center; + + @media (max-width: $breakpoint-tablet) { + grid-template-columns: 1fr; + gap: $spacing-lg; + } + + .overview-content { + h3 { + color: $white; + margin-bottom: $spacing-sm; + } + + p { + color: $light-gray; + font-size: 1.125rem; + line-height: 1.8; + margin-bottom: $spacing-sm; + } + } + + .overview-image { + text-align: center; + + img { + max-width: 100%; + height: auto; + border-radius: $border-radius-lg; + box-shadow: $shadow-xl; + } + } +} + +// Requirements List +.requirements-list { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); + gap: $spacing-md; + margin-top: $spacing-lg; + + .requirement-item { + display: flex; + align-items: center; + gap: $spacing-sm; + padding: $spacing-md $spacing-sm; + background-color: $white; + border-radius: $border-radius; + border-left: 4px solid $primary-red; + box-shadow: $shadow-sm; + transition: all $transition-speed $transition-ease; + + &:hover { + box-shadow: $shadow-md; + transform: translateY(-2px); + } + + .requirement-icon { + color: $primary-red; + font-size: 1.5rem; + flex-shrink: 0; + font-weight: bold; + } + + .requirement-text { + color: $dark-gray; + font-size: 1rem; + line-height: 1.5; + } + } +} + +// Documentation Card +.doc-card { + background-color: $white; + border-radius: $border-radius-lg; + padding: $spacing-xxl; + margin-bottom: $spacing-lg; + box-shadow: $shadow-sm; + border-left: 4px solid $primary-red; + line-height: 1.8; + + @media (max-width: $breakpoint-tablet) { + padding: $spacing-lg; + } + + // Headings with better spacing + h1 { + color: $dark-gray; + font-size: 2.5rem; + margin-bottom: $spacing-lg; + padding-bottom: $spacing-sm; + border-bottom: 2px solid $light-gray; + + @media (max-width: $breakpoint-tablet) { + font-size: 2rem; + } + } + + h2 { + color: $dark-gray; + font-size: 1.875rem; + margin-top: $spacing-xxl; + margin-bottom: $spacing-md; + padding-top: $spacing-md; + + @media (max-width: $breakpoint-tablet) { + font-size: 1.5rem; + margin-top: $spacing-lg; + } + } + + h3 { + color: $dark-gray; + font-size: 1.5rem; + margin-top: $spacing-lg; + margin-bottom: $spacing-sm; + + @media (max-width: $breakpoint-tablet) { + font-size: 1.25rem; + } + } + + h4 { + color: $medium-gray; + font-size: 1.25rem; + margin-top: $spacing-md; + margin-bottom: $spacing-sm; + font-weight: $font-weight-medium; + } + + // Paragraphs + p { + margin-bottom: $spacing-md; + color: $dark-gray; + font-size: 1.0625rem; + line-height: 1.8; + } + + // Lists with better spacing + ul, ol { + margin-bottom: $spacing-md; + margin-left: $spacing-md; + + li { + margin-bottom: $spacing-xs; + color: $dark-gray; + font-size: 1.0625rem; + line-height: 1.7; + } + } + + // Tables - cleaner, more readable + table { + width: 100%; + border-collapse: collapse; + margin: $spacing-lg 0; + font-size: 0.9375rem; + box-shadow: $shadow-sm; + border-radius: $border-radius; + overflow: hidden; + + thead { + background-color: $dark-gray; + color: $white; + + th { + padding: $spacing-sm $spacing-md; + text-align: left; + font-weight: $font-weight-medium; + border-bottom: 2px solid $primary-red; + } + } + + tbody { + tr { + border-bottom: 1px solid $light-gray; + + &:nth-child(even) { + background-color: #fafafa; + } + + &:hover { + background-color: rgba($primary-red, 0.05); + } + } + + td { + padding: $spacing-sm $spacing-md; + color: $dark-gray; + + code { + background-color: rgba($primary-red, 0.1); + color: $dark-red; + padding: 2px 6px; + border-radius: 3px; + font-size: 0.875em; + } + } + } + } + + // Code blocks - cleaner styling + pre { + background-color: #f8f8f8; + border: 1px solid #e0e0e0; + border-left: 4px solid $primary-red; + border-radius: $border-radius; + padding: $spacing-md; + overflow-x: auto; + margin: $spacing-md 0; + font-size: 0.9rem; + line-height: 1.6; + + code { + background-color: transparent; + color: $dark-gray; + font-family: $font-family-mono; + } + } + + // Inline code + code { + background-color: rgba($primary-red, 0.1); + color: $dark-red; + padding: 2px 6px; + border-radius: 3px; + font-size: 0.9em; + font-family: $font-family-mono; + } + + // Blockquotes + blockquote { + border-left: 4px solid $primary-red; + padding-left: $spacing-md; + margin: $spacing-md 0; + color: $medium-gray; + font-style: italic; + } + + // Links + a { + color: $primary-red; + text-decoration: none; + font-weight: $font-weight-medium; + transition: color $transition-speed $transition-ease; + + &:hover { + color: $dark-red; + text-decoration: underline; + } + } + + // Horizontal rules + hr { + border: none; + border-top: 2px solid $light-gray; + margin: $spacing-xxl 0; + } + + .doc-meta { + color: $medium-gray; + font-size: $font-size-small; + margin-bottom: $spacing-lg; + padding-bottom: $spacing-md; + border-bottom: 1px solid $light-gray; + } +} + +// Animations +@keyframes fadeInUp { + from { + opacity: 0; + transform: translateY(30px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +@keyframes float { + 0%, 100% { + transform: translateY(0px); + } + 50% { + transform: translateY(-20px); + } +} + +// Utility Classes +.text-center { + text-align: center; +} + +.mt-0 { margin-top: 0; } +.mt-1 { margin-top: $spacing-xs; } +.mt-2 { margin-top: $spacing-sm; } +.mt-3 { margin-top: $spacing-md; } +.mt-4 { margin-top: $spacing-lg; } + +.mb-0 { margin-bottom: 0; } +.mb-1 { margin-bottom: $spacing-xs; } +.mb-2 { margin-bottom: $spacing-sm; } +.mb-3 { margin-bottom: $spacing-md; } +.mb-4 { margin-bottom: $spacing-lg; } + +// Documentation Layout with Sidebar (Responsive) +.doc-layout { + display: grid; + grid-template-columns: 260px 1fr; + gap: $spacing-xxl; + align-items: start; + position: relative; + + // Tablet: narrower sidebar + @media (max-width: $breakpoint-desktop) and (min-width: $breakpoint-tablet) { + grid-template-columns: 220px 1fr; + gap: $spacing-lg; + } + + // Mobile: single column + @media (max-width: $breakpoint-tablet) { + grid-template-columns: 1fr; + gap: 0; + } +} + +.doc-sidebar { + position: sticky; + top: 90px; + max-height: calc(100vh - 120px); + overflow-y: auto; + + // Mobile: fixed overlay + @media (max-width: $breakpoint-tablet) { + position: fixed; + top: 70px; + left: -100%; + width: 280px; + max-width: 85vw; + height: calc(100vh - 70px); + background-color: rgba($black, 0.95); + backdrop-filter: blur(10px); + z-index: 999; + padding: $spacing-md; + transition: left $transition-speed $transition-ease; + overflow-y: auto; + box-shadow: $shadow-xl; + + &.mobile-open { + left: 0; + } + } + + // Custom scrollbar + &::-webkit-scrollbar { + width: 6px; + } + + &::-webkit-scrollbar-track { + background: transparent; + } + + &::-webkit-scrollbar-thumb { + background: rgba($medium-gray, 0.3); + border-radius: 3px; + + &:hover { + background: rgba($medium-gray, 0.5); + } + } +} + +.doc-main { + min-width: 0; + max-width: 900px; + + // Tablet and mobile: full width + @media (max-width: $breakpoint-desktop) { + max-width: 100%; + } +} + +// Mobile TOC Toggle Button +.doc-toc-mobile-toggle { + display: none; + + // Show on mobile and tablet + @media (max-width: $breakpoint-tablet) { + display: flex; + align-items: center; + justify-content: center; + gap: $spacing-xs; + width: 100%; + padding: $spacing-sm $spacing-md; + background: linear-gradient(135deg, $primary-red 0%, $dark-red 100%); + color: $white; + border: none; + border-radius: $border-radius; + font-weight: $font-weight-medium; + font-size: 1rem; + cursor: pointer; + margin-bottom: $spacing-md; + box-shadow: $shadow-md; + transition: all $transition-speed $transition-ease; + + &:hover { + transform: translateY(-2px); + box-shadow: $shadow-lg; + } + + &:active { + transform: translateY(0); + } + + span { + display: flex; + align-items: center; + gap: $spacing-xs; + } + } +} + +// Table of Contents +.doc-toc { + background-color: $white; + border-radius: $border-radius-lg; + padding: $spacing-md; + box-shadow: $shadow-sm; + border-left: 4px solid $primary-red; + + // Mobile: darker theme for overlay + @media (max-width: $breakpoint-tablet) { + background-color: $dark-gray; + border-left-color: $accent-red; + } + + .doc-toc-header { + margin-bottom: $spacing-md; + padding-bottom: $spacing-sm; + border-bottom: 2px solid $light-gray; + + @media (max-width: $breakpoint-tablet) { + border-bottom-color: $medium-gray; + } + + h3 { + font-size: 0.875rem; + font-weight: $font-weight-bold; + color: $dark-gray; + margin: 0; + text-transform: uppercase; + letter-spacing: 0.5px; + + @media (max-width: $breakpoint-tablet) { + color: $white; + } + } + } + + .doc-toc-list { + list-style: none; + padding: 0; + margin: 0; + + li { + margin-bottom: $spacing-xs; + } + + .toc-link { + display: block; + padding: $spacing-xs $spacing-sm; + color: $medium-gray; + text-decoration: none; + border-radius: $border-radius; + transition: all $transition-speed $transition-ease; + font-size: 0.9375rem; + line-height: 1.5; + border-left: 3px solid transparent; + + @media (max-width: $breakpoint-tablet) { + color: $light-gray; + font-size: 1rem; + padding: $spacing-sm; + } + + &:hover { + color: $primary-red; + background-color: rgba($primary-red, 0.1); + border-left-color: $primary-red; + padding-left: calc($spacing-sm + 3px); + + @media (max-width: $breakpoint-tablet) { + color: $accent-red; + background-color: rgba($accent-red, 0.15); + } + } + + &.active { + color: $primary-red; + background-color: rgba($primary-red, 0.15); + border-left-color: $primary-red; + font-weight: $font-weight-medium; + padding-left: calc($spacing-sm + 3px); + + @media (max-width: $breakpoint-tablet) { + color: $accent-red; + background-color: rgba($accent-red, 0.2); + border-left-color: $accent-red; + } + } + } + } +} + +// Mobile overlay backdrop +@media (max-width: $breakpoint-tablet) { + .doc-sidebar.mobile-open::before { + content: ''; + position: fixed; + top: 70px; + left: 0; + right: 0; + bottom: 0; + background-color: rgba($black, 0.5); + z-index: -1; + } +} + +// PDF Download Buttons +.doc-download-section { + display: flex; + gap: $spacing-sm; + margin-bottom: $spacing-lg; + padding-bottom: $spacing-lg; + border-bottom: 2px solid $light-gray; + flex-wrap: wrap; + + @media (max-width: $breakpoint-mobile) { + flex-direction: column; + } +} + +.btn-download-pdf { + display: inline-flex; + align-items: center; + gap: $spacing-xs; + padding: $spacing-sm $spacing-md; + background-color: $white; + color: $primary-red; + border: 2px solid $primary-red; + border-radius: $border-radius; + text-decoration: none; + font-weight: $font-weight-medium; + font-size: 0.9375rem; + transition: all $transition-speed $transition-ease; + box-shadow: $shadow-sm; + + svg { + flex-shrink: 0; + } + + &:hover { + background-color: $primary-red; + color: $white; + transform: translateY(-2px); + box-shadow: $shadow-md; + + svg { + animation: downloadBounce 0.6s ease-in-out; + } + } + + &:active { + transform: translateY(0); + } + + &.btn-download-complete { + background-color: $primary-red; + color: $white; + + &:hover { + background-color: $dark-red; + } + } + + @media (max-width: $breakpoint-mobile) { + justify-content: center; + width: 100%; + } +} + +// Download icon animation +@keyframes downloadBounce { + 0%, 100% { + transform: translateY(0); + } + 50% { + transform: translateY(3px); + } +} + +// Alert/Warning Boxes +.alert { + padding: $spacing-md $spacing-lg; + border-radius: $border-radius; + margin: $spacing-lg 0; + border-left: 4px solid; + + &.alert-warning { + background-color: #fff3cd; + border-left-color: #ffc107; + color: #856404; + + strong { + color: #856404; + } + } + + &.alert-info { + background-color: #d1ecf1; + border-left-color: #17a2b8; + color: #0c5460; + + strong { + color: #0c5460; + } + } + + &.alert-danger { + background-color: #f8d7da; + border-left-color: #dc3545; + color: #721c24; + + strong { + color: #721c24; + } + } + + &.alert-success { + background-color: #d4edda; + border-left-color: #28a745; + color: #155724; + + strong { + color: #155724; + } + } + + p:last-child { + margin-bottom: 0; + } +} diff --git a/gh_pages/_sass/_layout.scss b/gh_pages/_sass/_layout.scss new file mode 100644 index 0000000..e6d05bb --- /dev/null +++ b/gh_pages/_sass/_layout.scss @@ -0,0 +1,260 @@ +// Base Layout Styles +* { + box-sizing: border-box; + margin: 0; + padding: 0; +} + +html { + scroll-behavior: smooth; + font-size: $font-size-base; +} + +body { + font-family: $font-family-base; + line-height: $line-height-base; + color: $dark-gray; + background-color: $white; + overflow-x: hidden; +} + +// Container +.container { + max-width: $container-width; + margin: 0 auto; + padding: 0 $spacing-md; + + &.narrow { + max-width: $container-width-narrow; + } +} + +// Header +.site-header { + position: fixed; + top: 0; + left: 0; + right: 0; + z-index: 1000; + background-color: rgba($black, 0.95); + backdrop-filter: blur(10px); + box-shadow: $shadow-md; + transition: all $transition-speed $transition-ease; + + .header-content { + display: flex; + justify-content: space-between; + align-items: center; + padding: $spacing-sm 0; + } + + .site-title { + font-size: 1.5rem; + font-weight: $font-weight-bold; + color: $white; + text-decoration: none; + transition: color $transition-speed $transition-ease; + + &:hover { + color: $primary-red; + } + } +} + +// Navigation +.site-nav { + display: flex; + gap: $spacing-md; + align-items: center; + + a { + color: $light-gray; + text-decoration: none; + font-weight: $font-weight-medium; + transition: color $transition-speed $transition-ease; + padding: $spacing-xs $spacing-sm; + border-radius: $border-radius; + + &:hover { + color: $primary-red; + background-color: rgba($primary-red, 0.1); + } + } + + .mobile-menu-toggle { + display: none; + background: none; + border: none; + color: $white; + font-size: 1.5rem; + cursor: pointer; + padding: $spacing-xs; + } + + @media (max-width: $breakpoint-tablet) { + position: fixed; + top: 70px; + left: 0; + right: 0; + background-color: rgba($black, 0.98); + flex-direction: column; + padding: $spacing-md; + gap: $spacing-sm; + transform: translateY(-120%); + transition: transform $transition-speed $transition-ease; + box-shadow: $shadow-lg; + + &.active { + transform: translateY(0); + } + + .mobile-menu-toggle { + display: block; + } + + a { + width: 100%; + text-align: center; + padding: $spacing-sm; + } + } +} + +// Footer +.site-footer { + background-color: $black; + color: $light-gray; + padding: $spacing-xxl 0 $spacing-md; + margin-top: $spacing-xxl; + + .footer-content { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); + gap: $spacing-lg; + margin-bottom: $spacing-lg; + } + + .footer-section { + h3 { + color: $white; + margin-bottom: $spacing-sm; + font-size: $font-size-h4; + } + + ul { + list-style: none; + + li { + margin-bottom: $spacing-xs; + } + } + + a { + color: $light-gray; + text-decoration: none; + transition: color $transition-speed $transition-ease; + + &:hover { + color: $primary-red; + } + } + } + + .footer-bottom { + text-align: center; + padding-top: $spacing-md; + border-top: 1px solid $medium-gray; + color: $medium-gray; + font-size: $font-size-small; + } +} + +// Main Content +.main-content { + margin-top: 70px; // Height of fixed header + min-height: calc(100vh - 70px); +} + +// Section Spacing +.section { + padding: $spacing-xxl 0; + + &.section-dark { + background-color: $black; + color: $white; + } + + &.section-gray { + background-color: $light-gray; + } +} + +// Responsive Typography +h1, h2, h3, h4, h5, h6 { + font-family: $font-family-heading; + line-height: $line-height-heading; + font-weight: $font-weight-bold; + margin-bottom: $spacing-sm; +} + +h1 { + font-size: $font-size-h1; + + @media (max-width: $breakpoint-tablet) { + font-size: 2.5rem; + } +} + +h2 { + font-size: $font-size-h2; + + @media (max-width: $breakpoint-tablet) { + font-size: 2rem; + } +} + +h3 { + font-size: $font-size-h3; +} + +h4 { + font-size: $font-size-h4; +} + +p { + margin-bottom: $spacing-sm; +} + +// Links +a { + color: $primary-red; + transition: color $transition-speed $transition-ease; + + &:hover { + color: $dark-red; + } +} + +// Code +code { + font-family: $font-family-mono; + background-color: $light-gray; + padding: 2px 6px; + border-radius: 4px; + font-size: 0.9em; +} + +pre { + background-color: $dark-gray; + color: $light-gray; + padding: $spacing-sm; + border-radius: $border-radius; + overflow-x: auto; + margin-bottom: $spacing-sm; + + code { + background-color: transparent; + padding: 0; + color: inherit; + } +} diff --git a/gh_pages/_sass/_variables.scss b/gh_pages/_sass/_variables.scss new file mode 100644 index 0000000..cd83a3e --- /dev/null +++ b/gh_pages/_sass/_variables.scss @@ -0,0 +1,60 @@ +// Color Palette +$primary-red: #D32F2F; +$dark-red: #C62828; +$accent-red: #FF5252; +$black: #1a1a1a; +$dark-gray: #212121; +$medium-gray: #424242; +$light-gray: #F5F5F5; +$white: #FFFFFF; + +// Typography +$font-family-base: 'Inter', 'Roboto', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; +$font-family-heading: 'Inter', 'Roboto', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; +$font-family-mono: 'Consolas', 'Monaco', 'Courier New', monospace; + +$font-size-base: 16px; +$font-size-h1: 3.5rem; +$font-size-h2: 2.5rem; +$font-size-h3: 1.75rem; +$font-size-h4: 1.5rem; +$font-size-small: 0.875rem; + +$font-weight-light: 300; +$font-weight-normal: 400; +$font-weight-medium: 500; +$font-weight-bold: 700; + +$line-height-base: 1.6; +$line-height-heading: 1.2; + +// Spacing +$spacing-unit: 1rem; +$spacing-xs: $spacing-unit * 0.5; +$spacing-sm: $spacing-unit * 1; +$spacing-md: $spacing-unit * 2; +$spacing-lg: $spacing-unit * 3; +$spacing-xl: $spacing-unit * 4; +$spacing-xxl: $spacing-unit * 6; + +// Layout +$container-width: 1200px; +$container-width-narrow: 950px; +$border-radius: 8px; +$border-radius-lg: 12px; + +// Transitions +$transition-speed: 0.3s; +$transition-ease: cubic-bezier(0.4, 0, 0.2, 1); + +// Shadows +$shadow-sm: 0 2px 4px rgba(0, 0, 0, 0.1); +$shadow-md: 0 4px 8px rgba(0, 0, 0, 0.15); +$shadow-lg: 0 8px 16px rgba(0, 0, 0, 0.2); +$shadow-xl: 0 12px 24px rgba(0, 0, 0, 0.25); + +// Breakpoints +$breakpoint-mobile: 480px; +$breakpoint-tablet: 768px; +$breakpoint-desktop: 1024px; +$breakpoint-wide: 1280px; diff --git a/gh_pages/_site/Camera_Hero_NoBackground.png b/gh_pages/_site/Camera_Hero_NoBackground.png new file mode 100644 index 0000000..c8d1146 Binary files /dev/null and b/gh_pages/_site/Camera_Hero_NoBackground.png differ diff --git a/gh_pages/_site/DEPLOYMENT.html b/gh_pages/_site/DEPLOYMENT.html new file mode 100644 index 0000000..f352216 --- /dev/null +++ b/gh_pages/_site/DEPLOYMENT.html @@ -0,0 +1,496 @@ + + + + + + + + GitHub Pages Deployment Guide | Event Video Playback + + + + + +GitHub Pages Deployment Guide | Event Video Playback + + + + + + + + + + + + + + + + + + + +
+
+ +
+

GitHub Pages Deployment Guide

+
+ +
+

GitHub Pages Deployment Guide

+ +

This guide explains how to deploy the Event Video Playback website to GitHub Pages.

+ +

Prerequisites

+ +

Before deploying, ensure you have:

+
    +
  • Push access to the repository
  • +
  • GitHub Pages enabled in repository settings
  • +
+ +

Deployment Methods

+ + + +

The site automatically deploys when you push changes to the main or v2.0.0 branches.

+ +
    +
  1. Make your changes in the gh_pages/ directory
  2. +
  3. Commit your changes: +
    git add gh_pages/
    +git commit -m "Update website content"
    +
    +
  4. +
  5. Push to GitHub: +
    git push origin main
    +# or
    +git push origin v2.0.0
    +
    +
  6. +
  7. Monitor deployment: +
      +
    • Go to the repository Actions tab
    • +
    • Watch the “Deploy Jekyll site to GitHub Pages” workflow
    • +
    • Deployment typically takes 1-2 minutes
    • +
    +
  8. +
  9. View the live site: +
      +
    • https://beckhoff-usa-community.github.io/EventVideoPlayback/
    • +
    +
  10. +
+ +

Method 2: Manual Workflow Trigger

+ +

You can manually trigger a deployment from the GitHub Actions interface:

+ +
    +
  1. Go to the repository Actions tab
  2. +
  3. Select “Deploy Jekyll site to GitHub Pages”
  4. +
  5. Click “Run workflow”
  6. +
  7. Choose the branch (main or v2.0.0)
  8. +
  9. Click “Run workflow” button
  10. +
+ +

First-Time Setup

+ +

If this is the first deployment, you need to configure GitHub Pages settings:

+ +

Step 1: Enable GitHub Pages

+ +
    +
  1. Go to repository Settings > Pages
  2. +
  3. Under “Build and deployment”: +
      +
    • Source: Deploy from a branch (this will be changed automatically)
    • +
    • Or select: GitHub Actions (recommended)
    • +
    +
  4. +
+ +

Step 2: Set Permissions

+ +
    +
  1. Go to repository Settings > Actions > General
  2. +
  3. Scroll to “Workflow permissions”
  4. +
  5. Select: Read and write permissions
  6. +
  7. Check: Allow GitHub Actions to create and approve pull requests
  8. +
  9. Click Save
  10. +
+ +

Step 3: Configure Environment

+ +
    +
  1. Go to repository Settings > Environments
  2. +
  3. You should see a “github-pages” environment
  4. +
  5. If not, it will be created automatically on first deployment
  6. +
+ +

Step 4: First Deployment

+ +
    +
  1. Push any change to trigger deployment: +
    git add gh_pages/
    +git commit -m "Initial website deployment"
    +git push origin main
    +
    +
  2. +
  3. Go to Actions tab and watch the workflow
  4. +
  5. Wait for deployment to complete
  6. +
  7. The site URL will appear in the workflow output
  8. +
+ +

Verifying Deployment

+ +

Check Workflow Status

+ +
    +
  1. Actions Tab: View real-time build logs
  2. +
  3. Green checkmark: Deployment successful
  4. +
  5. Red X: Deployment failed (check logs for errors)
  6. +
+ +

Test the Live Site

+ +

Visit: https://beckhoff-usa-community.github.io/EventVideoPlayback/

+ +

Test checklist:

+
    +
  • Landing page loads correctly
  • +
  • Hero image displays
  • +
  • Navigation menu works
  • +
  • All documentation pages load
  • +
  • Internal links work
  • +
  • Styles and colors are correct
  • +
  • Mobile responsive design works
  • +
  • JavaScript animations work
  • +
+ +

Troubleshooting

+ +

Deployment Fails

+ +

Error: “Process completed with exit code 16”

+
    +
  • Jekyll build failed
  • +
  • Check syntax in Markdown files
  • +
  • Verify YAML front matter is correct
  • +
  • Review GitHub Actions logs for specific errors
  • +
+ +

Fix:

+
# Test build locally
+cd gh_pages
+bundle exec jekyll build
+# Fix any errors shown
+
+ +

Error: “No uploaded artifact was found”

+
    +
  • Build completed but artifact upload failed
  • +
  • Usually temporary; retry deployment
  • +
+ +

Fix:

+
    +
  • Re-run the workflow from Actions tab
  • +
  • Check GitHub status page for outages
  • +
+ +

Site Not Updating

+ +

Changes not visible after deployment:

+ +
    +
  1. Wait: CDN propagation can take 1-2 minutes
  2. +
  3. Clear cache: +
      +
    • Hard refresh: Ctrl+Shift+R (Windows) or Cmd+Shift+R (Mac)
    • +
    • Open in private/incognito window
    • +
    +
  4. +
  5. Verify deployment: +
      +
    • Check Actions tab shows successful deployment
    • +
    • Verify commit SHA matches latest push
    • +
    +
  6. +
+ +

404 Errors on Navigation

+ +

Internal links showing 404:

+ +
    +
  1. Check _config.yml baseurl is correct: +
    baseurl: "/EventVideoPlayback"
    +
    +
  2. +
  3. Verify links use relative_url filter: +
    /EventVideoPlayback/docs/getting-started/
    +
    +
  4. +
  5. Check permalinks in front matter match navigation links
  6. +
+ +

Styles Not Loading

+ +

CSS not applied:

+ +
    +
  1. Check assets/css/style.scss has front matter: +
    ---
    +---
    +
    +
  2. +
  3. Verify SCSS files are imported: +
    @import "variables";
    +@import "layout";
    +@import "components";
    +
    +
  4. +
  5. Clear browser cache and try again
  6. +
+ +

Images Not Loading

+ +

Hero image or other images broken:

+ +
    +
  1. Verify image path: +
    /EventVideoPlayback/assets/images/Camera_Hero_NoBackground.png
    +
    +
  2. +
  3. Check image exists in assets/images/
  4. +
  5. Verify image filename matches (case-sensitive)
  6. +
+ +

Workflow Details

+ +

The deployment workflow (.github/workflows/pages.yml) performs these steps:

+ +
    +
  1. Checkout: Gets the repository code
  2. +
  3. Setup Ruby: Installs Ruby 3.1 and dependencies
  4. +
  5. Setup Pages: Configures GitHub Pages
  6. +
  7. Build Jekyll: Compiles the site with production settings
  8. +
  9. Upload Artifact: Packages the built site
  10. +
  11. Deploy: Publishes to GitHub Pages
  12. +
+ +

Workflow Triggers

+ +

The workflow runs when:

+
    +
  • Pushing to main or v2.0.0 branches
  • +
  • Only if files in gh_pages/ or workflow file change
  • +
  • Manually triggered via Actions tab
  • +
+ +

Build Time

+ +

Typical build and deployment: 1-2 minutes

+ +

Breakdown:

+
    +
  • Checkout: 5-10 seconds
  • +
  • Ruby setup: 20-30 seconds
  • +
  • Jekyll build: 15-30 seconds
  • +
  • Deploy: 30-60 seconds
  • +
+ +

Making Changes Safely

+ +

Best Practices

+ +
    +
  1. Test Locally First: +
    cd gh_pages
    +bundle exec jekyll serve
    +# Test at http://localhost:4000/EventVideoPlayback/
    +
    +
  2. +
  3. Use Feature Branches: +
    git checkout -b update-documentation
    +# Make changes
    +git commit -m "Update documentation"
    +git push origin update-documentation
    +# Create pull request for review
    +
    +
  4. +
  5. Review Before Merge: +
      +
    • Check pull request preview
    • +
    • Verify changes in GitHub’s file view
    • +
    • Review with team if needed
    • +
    +
  6. +
  7. Monitor Deployment: +
      +
    • Watch Actions tab after merge
    • +
    • Test live site immediately after deployment
    • +
    • Be ready to rollback if issues occur
    • +
    +
  8. +
+ +

Emergency Rollback

+ +

If a deployment breaks the site:

+ +
    +
  1. Revert the commit: +
    git revert HEAD
    +git push origin main
    +
    +
  2. +
  3. Or reset to previous version: +
    git reset --hard <previous-commit-sha>
    +git push origin main --force
    +
    +
  4. +
  5. Or checkout previous version: +
    git checkout <previous-commit-sha> gh_pages/
    +git commit -m "Rollback to previous version"
    +git push origin main
    +
    +
  6. +
+ +

Performance Optimization

+ +

Image Optimization

+ +

Before adding images:

+
# Optimize PNG
+optipng -o7 assets/images/image.png
+
+# Or use ImageMagick
+convert input.png -strip -quality 85 output.png
+
+ +

Build Optimization

+ +

The workflow uses:

+
    +
  • Bundler cache for faster Ruby setup
  • +
  • Incremental builds (when possible)
  • +
  • Production environment for optimized output
  • +
+ +

Monitoring

+ +

GitHub Pages Status

+ +

Check: https://www.githubstatus.com/

+ +

Look for issues with:

+
    +
  • GitHub Pages
  • +
  • GitHub Actions
  • +
  • Git Operations
  • +
+ +

Site Analytics

+ +

Consider adding:

+
    +
  • Google Analytics
  • +
  • GitHub Traffic Stats (Settings > Insights > Traffic)
  • +
+ +

Support

+ +

Issues with deployment?

+ +
    +
  1. Check GitHub Actions logs
  2. +
  3. Review GitHub Pages documentation
  4. +
  5. Check Jekyll documentation
  6. +
  7. Open an issue in the repository
  8. +
+ +

Additional Resources

+ + + +
+ +
+ +
+ + + + + + + diff --git a/gh_pages/_site/DEPLOYMENT.md b/gh_pages/_site/DEPLOYMENT.md new file mode 100644 index 0000000..f0138bc --- /dev/null +++ b/gh_pages/_site/DEPLOYMENT.md @@ -0,0 +1,325 @@ +# GitHub Pages Deployment Guide + +This guide explains how to deploy the Event Video Playback website to GitHub Pages. + +## Prerequisites + +Before deploying, ensure you have: +- Push access to the repository +- GitHub Pages enabled in repository settings + +## Deployment Methods + +### Method 1: Automatic Deployment (Recommended) + +The site automatically deploys when you push changes to the `main` or `v2.0.0` branches. + +1. **Make your changes** in the `gh_pages/` directory +2. **Commit your changes**: + ```bash + git add gh_pages/ + git commit -m "Update website content" + ``` +3. **Push to GitHub**: + ```bash + git push origin main + # or + git push origin v2.0.0 + ``` +4. **Monitor deployment**: + - Go to the repository **Actions** tab + - Watch the "Deploy Jekyll site to GitHub Pages" workflow + - Deployment typically takes 1-2 minutes + +5. **View the live site**: + - https://beckhoff-usa-community.github.io/EventVideoPlayback/ + +### Method 2: Manual Workflow Trigger + +You can manually trigger a deployment from the GitHub Actions interface: + +1. Go to the repository **Actions** tab +2. Select "Deploy Jekyll site to GitHub Pages" +3. Click "Run workflow" +4. Choose the branch (main or v2.0.0) +5. Click "Run workflow" button + +## First-Time Setup + +If this is the first deployment, you need to configure GitHub Pages settings: + +### Step 1: Enable GitHub Pages + +1. Go to repository **Settings** > **Pages** +2. Under "Build and deployment": + - **Source**: Deploy from a branch (this will be changed automatically) + - Or select: **GitHub Actions** (recommended) + +### Step 2: Set Permissions + +1. Go to repository **Settings** > **Actions** > **General** +2. Scroll to "Workflow permissions" +3. Select: **Read and write permissions** +4. Check: **Allow GitHub Actions to create and approve pull requests** +5. Click **Save** + +### Step 3: Configure Environment + +1. Go to repository **Settings** > **Environments** +2. You should see a "github-pages" environment +3. If not, it will be created automatically on first deployment + +### Step 4: First Deployment + +1. Push any change to trigger deployment: + ```bash + git add gh_pages/ + git commit -m "Initial website deployment" + git push origin main + ``` + +2. Go to **Actions** tab and watch the workflow +3. Wait for deployment to complete +4. The site URL will appear in the workflow output + +## Verifying Deployment + +### Check Workflow Status + +1. **Actions Tab**: View real-time build logs +2. **Green checkmark**: Deployment successful +3. **Red X**: Deployment failed (check logs for errors) + +### Test the Live Site + +Visit: https://beckhoff-usa-community.github.io/EventVideoPlayback/ + +**Test checklist:** +- [ ] Landing page loads correctly +- [ ] Hero image displays +- [ ] Navigation menu works +- [ ] All documentation pages load +- [ ] Internal links work +- [ ] Styles and colors are correct +- [ ] Mobile responsive design works +- [ ] JavaScript animations work + +## Troubleshooting + +### Deployment Fails + +**Error: "Process completed with exit code 16"** +- Jekyll build failed +- Check syntax in Markdown files +- Verify YAML front matter is correct +- Review GitHub Actions logs for specific errors + +**Fix:** +```bash +# Test build locally +cd gh_pages +bundle exec jekyll build +# Fix any errors shown +``` + +**Error: "No uploaded artifact was found"** +- Build completed but artifact upload failed +- Usually temporary; retry deployment + +**Fix:** +- Re-run the workflow from Actions tab +- Check GitHub status page for outages + +### Site Not Updating + +**Changes not visible after deployment:** + +1. **Wait**: CDN propagation can take 1-2 minutes +2. **Clear cache**: + - Hard refresh: `Ctrl+Shift+R` (Windows) or `Cmd+Shift+R` (Mac) + - Open in private/incognito window +3. **Verify deployment**: + - Check Actions tab shows successful deployment + - Verify commit SHA matches latest push + +### 404 Errors on Navigation + +**Internal links showing 404:** + +1. Check `_config.yml` baseurl is correct: + ```yaml + baseurl: "/EventVideoPlayback" + ``` + +2. Verify links use `relative_url` filter: + ```liquid + {{ '/docs/getting-started/' | relative_url }} + ``` + +3. Check permalinks in front matter match navigation links + +### Styles Not Loading + +**CSS not applied:** + +1. Check `assets/css/style.scss` has front matter: + ```yaml + --- + --- + ``` + +2. Verify SCSS files are imported: + ```scss + @import "variables"; + @import "layout"; + @import "components"; + ``` + +3. Clear browser cache and try again + +### Images Not Loading + +**Hero image or other images broken:** + +1. Verify image path: + ```liquid + {{ '/assets/images/Camera_Hero_NoBackground.png' | relative_url }} + ``` + +2. Check image exists in `assets/images/` +3. Verify image filename matches (case-sensitive) + +## Workflow Details + +The deployment workflow (`.github/workflows/pages.yml`) performs these steps: + +1. **Checkout**: Gets the repository code +2. **Setup Ruby**: Installs Ruby 3.1 and dependencies +3. **Setup Pages**: Configures GitHub Pages +4. **Build Jekyll**: Compiles the site with production settings +5. **Upload Artifact**: Packages the built site +6. **Deploy**: Publishes to GitHub Pages + +### Workflow Triggers + +The workflow runs when: +- Pushing to `main` or `v2.0.0` branches +- Only if files in `gh_pages/` or workflow file change +- Manually triggered via Actions tab + +### Build Time + +Typical build and deployment: **1-2 minutes** + +Breakdown: +- Checkout: 5-10 seconds +- Ruby setup: 20-30 seconds +- Jekyll build: 15-30 seconds +- Deploy: 30-60 seconds + +## Making Changes Safely + +### Best Practices + +1. **Test Locally First**: + ```bash + cd gh_pages + bundle exec jekyll serve + # Test at http://localhost:4000/EventVideoPlayback/ + ``` + +2. **Use Feature Branches**: + ```bash + git checkout -b update-documentation + # Make changes + git commit -m "Update documentation" + git push origin update-documentation + # Create pull request for review + ``` + +3. **Review Before Merge**: + - Check pull request preview + - Verify changes in GitHub's file view + - Review with team if needed + +4. **Monitor Deployment**: + - Watch Actions tab after merge + - Test live site immediately after deployment + - Be ready to rollback if issues occur + +### Emergency Rollback + +If a deployment breaks the site: + +1. **Revert the commit**: + ```bash + git revert HEAD + git push origin main + ``` + +2. **Or reset to previous version**: + ```bash + git reset --hard + git push origin main --force + ``` + +3. **Or checkout previous version**: + ```bash + git checkout gh_pages/ + git commit -m "Rollback to previous version" + git push origin main + ``` + +## Performance Optimization + +### Image Optimization + +Before adding images: +```bash +# Optimize PNG +optipng -o7 assets/images/image.png + +# Or use ImageMagick +convert input.png -strip -quality 85 output.png +``` + +### Build Optimization + +The workflow uses: +- Bundler cache for faster Ruby setup +- Incremental builds (when possible) +- Production environment for optimized output + +## Monitoring + +### GitHub Pages Status + +Check: https://www.githubstatus.com/ + +Look for issues with: +- GitHub Pages +- GitHub Actions +- Git Operations + +### Site Analytics + +Consider adding: +- Google Analytics +- GitHub Traffic Stats (Settings > Insights > Traffic) + +## Support + +**Issues with deployment?** + +1. Check [GitHub Actions logs](../../actions) +2. Review [GitHub Pages documentation](https://docs.github.com/en/pages) +3. Check [Jekyll documentation](https://jekyllrb.com/docs/) +4. Open an issue in the repository + +## Additional Resources + +- [GitHub Pages Documentation](https://docs.github.com/en/pages) +- [Jekyll Documentation](https://jekyllrb.com/docs/) +- [GitHub Actions Documentation](https://docs.github.com/en/actions) +- [Repository Settings](../../settings) +- [View Deployments](../../deployments/github-pages) diff --git a/gh_pages/_site/Event Video Playback Configuration.html b/gh_pages/_site/Event Video Playback Configuration.html new file mode 100644 index 0000000..3b57a83 --- /dev/null +++ b/gh_pages/_site/Event Video Playback Configuration.html @@ -0,0 +1,190 @@ + + + + + + + + Event Video Playback Configuration | Event Video Playback + + + + + +Event Video Playback Configuration | Event Video Playback + + + + + + + + + + + + + + + + + + + +
+
+ +
+

Event Video Playback Configuration

+
+ +
+ +

Event Video Playback Configuration

+ +

EventVideoPlayback Service Configuration

+ +

The EventVideoPlayback Service controls the creation of the video and automatic deletion of video files based on video age and folder max size

+ +

The EventVideoPlayback Service reads the configuration file on startup. You must restart the service for changes to take effect. A reboot will also work. To stop and start the service, open the Windows Services window -> Right-click the EventVideoPlayback service and choose Stop or Start.

+ +

The config file is located atC:\Program Files\Beckhoff USA Community\EventVideoPlayback\Service\EventVideoPlaybackService.config.json

+ +

Open the file with notepad or Visual Studio and you will see the following parameters

+ +
{
+  "CodecFourCC": "avc1",
+  "VideoDeleteTime": 1,
+  "AdsPort": 26129,
+  "MaxFolderSize": 250
+}
+
+ +

CodecFourCC

+ +

This is the codec used to create the video from the service. avc1 is the most common codec that is also compatible with web browsers. For a full list of codecs see below, but not all are web compatible and will display as a black box on Tc HMI. Check here for appropriate codecs.

+ +
OpenCV: FFMPEG: format mp4 / MP4 (MPEG-4 Part 14)
+fourcc tag 0x7634706d/'mp4v' codec_id 000C
+fourcc tag 0x31637661/'avc1' codec_id 001B
+fourcc tag 0x33637661/'avc3' codec_id 001B
+fourcc tag 0x31766568/'hev1' codec_id 00AD
+fourcc tag 0x31637668/'hvc1' codec_id 00AD
+fourcc tag 0x7634706d/'mp4v' codec_id 0002
+fourcc tag 0x7634706d/'mp4v' codec_id 0001
+fourcc tag 0x7634706d/'mp4v' codec_id 0007
+fourcc tag 0x7634706d/'mp4v' codec_id 003D
+fourcc tag 0x7634706d/'mp4v' codec_id 0058
+fourcc tag 0x312d6376/'vc-1' codec_id 0046
+fourcc tag 0x63617264/'drac' codec_id 0074
+fourcc tag 0x7634706d/'mp4v' codec_id 00A3
+fourcc tag 0x39307076/'vp09' codec_id 00A7
+fourcc tag 0x31307661/'av01' codec_id 801D
+fourcc tag 0x6134706d/'mp4a' codec_id 15002
+fourcc tag 0x63616c61/'alac' codec_id 15010
+fourcc tag 0x6134706d/'mp4a' codec_id 1502D
+fourcc tag 0x6134706d/'mp4a' codec_id 15001
+fourcc tag 0x6134706d/'mp4a' codec_id 15000
+fourcc tag 0x332d6361/'ac-3' codec_id 15003
+fourcc tag 0x332d6365/'ec-3' codec_id 15028
+fourcc tag 0x6134706d/'mp4a' codec_id 15004
+fourcc tag 0x61706c6d/'mlpa' codec_id 1502C
+fourcc tag 0x43614c66/'fLaC' codec_id 1500C
+fourcc tag 0x7375704f/'Opus' codec_id 1503C
+fourcc tag 0x6134706d/'mp4a' codec_id 15005
+fourcc tag 0x6134706d/'mp4a' codec_id 15018
+fourcc tag 0x6134706d/'mp4a' codec_id 15803
+fourcc tag 0x7334706d/'mp4s' codec_id 17000
+fourcc tag 0x67337874/'tx3g' codec_id 17005
+fourcc tag 0x646d7067/'gpmd' codec_id 18807
+fourcc tag 0x316d686d/'mhm1' codec_id 15817
+
+ +

VideoDeleteTime

+ +

This is the amount of time that the file will stay stored on the system. If the time expired, the service will automatically cleanup old video files.

+ +

The value is a floating point value, and is in units of Days. So for half a day you will need to put 0.5 as the value.

+ +

AdsPort

+ +

Do not change. This is the ADS Port that the service is hosting on. This should remain at port 26129 at all times in order for the PLC function blocks to work properly.

+ +

MaxFolderSize

+ +

This is the Max size of the folder holding videos. When a new video is created, the folder size is checked and the oldest video will be deleted if required.

+ +

The value is a integer point value, and is in units of MB.

+ +

####

+ +
+ +
+ +
+ + + + + + + diff --git a/gh_pages/_site/Event Video Playback Configuration.md b/gh_pages/_site/Event Video Playback Configuration.md new file mode 100644 index 0000000..22a7a9c --- /dev/null +++ b/gh_pages/_site/Event Video Playback Configuration.md @@ -0,0 +1,82 @@ + +# Event Video Playback Configuration + + + +## EventVideoPlayback Service Configuration + +The EventVideoPlayback Service controls the creation of the video and automatic deletion of video files based on video age and folder max size + +The EventVideoPlayback Service reads the configuration file on startup. You must restart the service for changes to take effect. A reboot will also work. To stop and start the service, open the Windows Services window -> Right-click the EventVideoPlayback service and choose Stop or Start. + +The config file is located at```C:\Program Files\Beckhoff USA Community\EventVideoPlayback\Service\EventVideoPlaybackService.config.json``` + +Open the file with notepad or Visual Studio and you will see the following parameters + +```json +{ + "CodecFourCC": "avc1", + "VideoDeleteTime": 1, + "AdsPort": 26129, + "MaxFolderSize": 250 +} +``` + +#### CodecFourCC + +This is the codec used to create the video from the service. avc1 is the most common codec that is also compatible with web browsers. For a full list of codecs see below, but not all are web compatible and will display as a black box on Tc HMI. [Check here for appropriate codecs](https://developer.mozilla.org/en-US/docs/Web/Media/Formats/Video_codecs). + +``` +OpenCV: FFMPEG: format mp4 / MP4 (MPEG-4 Part 14) +fourcc tag 0x7634706d/'mp4v' codec_id 000C +fourcc tag 0x31637661/'avc1' codec_id 001B +fourcc tag 0x33637661/'avc3' codec_id 001B +fourcc tag 0x31766568/'hev1' codec_id 00AD +fourcc tag 0x31637668/'hvc1' codec_id 00AD +fourcc tag 0x7634706d/'mp4v' codec_id 0002 +fourcc tag 0x7634706d/'mp4v' codec_id 0001 +fourcc tag 0x7634706d/'mp4v' codec_id 0007 +fourcc tag 0x7634706d/'mp4v' codec_id 003D +fourcc tag 0x7634706d/'mp4v' codec_id 0058 +fourcc tag 0x312d6376/'vc-1' codec_id 0046 +fourcc tag 0x63617264/'drac' codec_id 0074 +fourcc tag 0x7634706d/'mp4v' codec_id 00A3 +fourcc tag 0x39307076/'vp09' codec_id 00A7 +fourcc tag 0x31307661/'av01' codec_id 801D +fourcc tag 0x6134706d/'mp4a' codec_id 15002 +fourcc tag 0x63616c61/'alac' codec_id 15010 +fourcc tag 0x6134706d/'mp4a' codec_id 1502D +fourcc tag 0x6134706d/'mp4a' codec_id 15001 +fourcc tag 0x6134706d/'mp4a' codec_id 15000 +fourcc tag 0x332d6361/'ac-3' codec_id 15003 +fourcc tag 0x332d6365/'ec-3' codec_id 15028 +fourcc tag 0x6134706d/'mp4a' codec_id 15004 +fourcc tag 0x61706c6d/'mlpa' codec_id 1502C +fourcc tag 0x43614c66/'fLaC' codec_id 1500C +fourcc tag 0x7375704f/'Opus' codec_id 1503C +fourcc tag 0x6134706d/'mp4a' codec_id 15005 +fourcc tag 0x6134706d/'mp4a' codec_id 15018 +fourcc tag 0x6134706d/'mp4a' codec_id 15803 +fourcc tag 0x7334706d/'mp4s' codec_id 17000 +fourcc tag 0x67337874/'tx3g' codec_id 17005 +fourcc tag 0x646d7067/'gpmd' codec_id 18807 +fourcc tag 0x316d686d/'mhm1' codec_id 15817 +``` + +#### VideoDeleteTime + +This is the amount of time that the file will stay stored on the system. If the time expired, the service will automatically cleanup old video files. + +The value is a floating point value, and is in units of Days. So for half a day you will need to put 0.5 as the value. + +#### AdsPort + +Do not change. This is the ADS Port that the service is hosting on. This should remain at port 26129 at all times in order for the PLC function blocks to work properly. + +#### MaxFolderSize + +This is the Max size of the folder holding videos. When a new video is created, the folder size is checked and the oldest video will be deleted if required. + +The value is a integer point value, and is in units of MB. + +#### diff --git a/gh_pages/_site/README.md b/gh_pages/_site/README.md new file mode 100644 index 0000000..7866949 --- /dev/null +++ b/gh_pages/_site/README.md @@ -0,0 +1,216 @@ +# Event Video Playback - GitHub Pages Website + +This directory contains the Jekyll-based GitHub Pages website for the Event Video Playback project. + +## 🚀 Quick Start + +### Local Development + +1. **Install Ruby and Jekyll** (if not already installed): + - Windows: Use [RubyInstaller](https://rubyinstaller.org/) + - macOS: `brew install ruby` + - Linux: `sudo apt-get install ruby-full` + +2. **Install dependencies**: + ```bash + cd gh_pages + bundle install + ``` + +3. **Run the local server**: + ```bash + bundle exec jekyll serve + ``` + +4. **View the site**: + Open http://localhost:4000/EventVideoPlayback/ in your browser + +### Automatic Deployment + +The site automatically deploys to GitHub Pages when you push changes to the `main` or `v2.0.0` branches. The deployment is handled by the GitHub Actions workflow at `.github/workflows/pages.yml`. + +**Live Site**: https://beckhoff-usa-community.github.io/EventVideoPlayback/ + +## 📁 Directory Structure + +``` +gh_pages/ +├── _config.yml # Jekyll configuration +├── Gemfile # Ruby dependencies +├── index.md # Landing page (hero section) +├── _layouts/ # Page layouts +│ ├── default.html # Base layout with header/footer +│ ├── home.html # Landing page layout +│ └── doc.html # Documentation page layout +├── _includes/ # Reusable components +│ ├── header.html # Site header with navigation +│ └── footer.html # Site footer +├── _docs/ # Documentation pages +│ ├── getting-started.md # Installation guide +│ ├── plc-usage.md # PLC library documentation +│ ├── service-config.md # Service configuration guide +│ └── hmi-usage.md # HMI NuGet package guide +├── _sass/ # SCSS stylesheets +│ ├── _variables.scss # Color scheme and design tokens +│ ├── _layout.scss # Layout styles +│ └── _components.scss # Component styles (hero, cards, etc.) +├── assets/ +│ ├── css/ +│ │ └── style.scss # Main stylesheet (imports all SCSS) +│ ├── js/ +│ │ └── main.js # JavaScript for interactions +│ └── images/ +│ └── Camera_Hero_NoBackground.png # Hero image +└── README.md # This file +``` + +## 🎨 Design System + +### Color Palette + +- **Primary Red**: `#D32F2F` +- **Dark Red**: `#C62828` +- **Accent Red**: `#FF5252` +- **Black**: `#1a1a1a` +- **Dark Gray**: `#212121` +- **Light Gray**: `#F5F5F5` +- **White**: `#FFFFFF` + +### Typography + +- **Font**: Inter (from Google Fonts) +- **Base Size**: 16px +- **Line Height**: 1.6 + +### Breakpoints + +- **Mobile**: 480px +- **Tablet**: 768px +- **Desktop**: 1024px +- **Wide**: 1280px + +## 📝 Updating Content + +### Modifying the Landing Page + +Edit `index.md` to change: +- Hero section text and buttons +- Feature cards +- Overview section +- System requirements +- Call-to-action sections + +### Updating Documentation + +Documentation pages are in the `_docs/` directory: + +1. **Getting Started** (`_docs/getting-started.md`): Installation and setup +2. **PLC Library Usage** (`_docs/plc-usage.md`): Function blocks and examples +3. **Service Configuration** (`_docs/service-config.md`): Windows service settings +4. **HMI Usage** (`_docs/hmi-usage.md`): WPF control integration + +Each documentation page uses the `doc` layout and includes: +```yaml +--- +layout: doc +title: Page Title +description: Brief description +permalink: /docs/page-name/ +--- +``` + +### Adding New Pages + +1. Create a new Markdown file in `_docs/` +2. Add front matter with layout, title, description, and permalink +3. Add the page to `_config.yml` under `header_pages` +4. Update navigation in `_includes/header.html` if needed + +## 🎯 Customization + +### Changing Colors + +Edit `_sass/_variables.scss` to modify the color scheme: + +```scss +$primary-red: #D32F2F; // Your primary color +$dark-red: #C62828; // Darker variant +$accent-red: #FF5252; // Accent color +``` + +### Modifying Styles + +- **Layout styles**: `_sass/_layout.scss` +- **Component styles**: `_sass/_components.scss` +- **Variables**: `_sass/_variables.scss` + +### Adding JavaScript + +Edit `assets/js/main.js` to add interactive features. + +## 🔧 Configuration + +Key settings in `_config.yml`: + +```yaml +title: Event Video Playback +description: Transform TwinCAT Vision images into event-driven video recordings +baseurl: "/EventVideoPlayback" +url: "https://beckhoff-usa-community.github.io" +``` + +## 🚨 Troubleshooting + +### Site not updating after push + +1. Check GitHub Actions status in the **Actions** tab +2. Verify the workflow ran successfully +3. Wait 1-2 minutes for changes to propagate +4. Clear browser cache and refresh + +### Styles not loading + +1. Ensure `assets/css/style.scss` has front matter (`---` at the top) +2. Check that SCSS files in `_sass/` are properly imported +3. Verify file paths are correct + +### Navigation links broken + +1. Check `_config.yml` for correct `baseurl` +2. Use Liquid tags for links: `{{ '/docs/page/' | relative_url }}` +3. Ensure permalink in front matter matches navigation links + +### Local build fails + +```bash +# Clear Jekyll cache +bundle exec jekyll clean + +# Reinstall dependencies +bundle install + +# Try building again +bundle exec jekyll serve +``` + +## 📚 Resources + +- [Jekyll Documentation](https://jekyllrb.com/docs/) +- [GitHub Pages Documentation](https://docs.github.com/en/pages) +- [Liquid Template Language](https://shopify.github.io/liquid/) +- [Markdown Guide](https://www.markdownguide.org/) + +## 🤝 Contributing + +When updating the website: + +1. Test changes locally first with `bundle exec jekyll serve` +2. Check responsive design on mobile, tablet, and desktop +3. Verify all links work +4. Ensure images load correctly +5. Test navigation between pages +6. Push to a branch and create a pull request + +## 📄 License + +This website content is part of the Event Video Playback project and is licensed under the MIT License. See the [LICENSE](../LICENSE) file in the repository root. diff --git a/gh_pages/_site/assets/css/style.css b/gh_pages/_site/assets/css/style.css new file mode 100644 index 0000000..d495556 --- /dev/null +++ b/gh_pages/_site/assets/css/style.css @@ -0,0 +1,224 @@ +@import url("https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;700&display=swap"); +* { box-sizing: border-box; margin: 0; padding: 0; } + +html { scroll-behavior: smooth; font-size: 16px; } + +body { font-family: "Inter", "Roboto", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; line-height: 1.6; color: #212121; background-color: #FFFFFF; overflow-x: hidden; } + +.container { max-width: 1200px; margin: 0 auto; padding: 0 2rem; } +.container.narrow { max-width: 950px; } + +.site-header { position: fixed; top: 0; left: 0; right: 0; z-index: 1000; background-color: rgba(26, 26, 26, 0.95); backdrop-filter: blur(10px); box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15); transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); } +.site-header .header-content { display: flex; justify-content: space-between; align-items: center; padding: 1rem 0; } +.site-header .site-title { font-size: 1.5rem; font-weight: 700; color: #FFFFFF; text-decoration: none; transition: color 0.3s cubic-bezier(0.4, 0, 0.2, 1); } +.site-header .site-title:hover { color: #D32F2F; } + +.site-nav { display: flex; gap: 2rem; align-items: center; } +.site-nav a { color: #F5F5F5; text-decoration: none; font-weight: 500; transition: color 0.3s cubic-bezier(0.4, 0, 0.2, 1); padding: 0.5rem 1rem; border-radius: 8px; } +.site-nav a:hover { color: #D32F2F; background-color: rgba(211, 47, 47, 0.1); } +.site-nav .mobile-menu-toggle { display: none; background: none; border: none; color: #FFFFFF; font-size: 1.5rem; cursor: pointer; padding: 0.5rem; } +@media (max-width: 768px) { .site-nav { position: fixed; top: 70px; left: 0; right: 0; background-color: rgba(26, 26, 26, 0.98); flex-direction: column; padding: 2rem; gap: 1rem; transform: translateY(-120%); transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1); box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2); } + .site-nav.active { transform: translateY(0); } + .site-nav .mobile-menu-toggle { display: block; } + .site-nav a { width: 100%; text-align: center; padding: 1rem; } } + +.site-footer { background-color: #1a1a1a; color: #F5F5F5; padding: 6rem 0 2rem; margin-top: 6rem; } +.site-footer .footer-content { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 3rem; margin-bottom: 3rem; } +.site-footer .footer-section h3 { color: #FFFFFF; margin-bottom: 1rem; font-size: 1.5rem; } +.site-footer .footer-section ul { list-style: none; } +.site-footer .footer-section ul li { margin-bottom: 0.5rem; } +.site-footer .footer-section a { color: #F5F5F5; text-decoration: none; transition: color 0.3s cubic-bezier(0.4, 0, 0.2, 1); } +.site-footer .footer-section a:hover { color: #D32F2F; } +.site-footer .footer-bottom { text-align: center; padding-top: 2rem; border-top: 1px solid #424242; color: #424242; font-size: 0.875rem; } + +.main-content { margin-top: 70px; min-height: calc(100vh - 70px); } + +.section { padding: 6rem 0; } +.section.section-dark { background-color: #1a1a1a; color: #FFFFFF; } +.section.section-gray { background-color: #F5F5F5; } + +h1, h2, h3, h4, h5, h6 { font-family: "Inter", "Roboto", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; line-height: 1.2; font-weight: 700; margin-bottom: 1rem; } + +h1 { font-size: 3.5rem; } +@media (max-width: 768px) { h1 { font-size: 2.5rem; } } + +h2 { font-size: 2.5rem; } +@media (max-width: 768px) { h2 { font-size: 2rem; } } + +h3 { font-size: 1.75rem; } + +h4 { font-size: 1.5rem; } + +p { margin-bottom: 1rem; } + +a { color: #D32F2F; transition: color 0.3s cubic-bezier(0.4, 0, 0.2, 1); } +a:hover { color: #C62828; } + +code { font-family: "Consolas", "Monaco", "Courier New", monospace; background-color: #F5F5F5; padding: 2px 6px; border-radius: 4px; font-size: 0.9em; } + +pre { background-color: #212121; color: #F5F5F5; padding: 1rem; border-radius: 8px; overflow-x: auto; margin-bottom: 1rem; } +pre code { background-color: transparent; padding: 0; color: inherit; } + +.hero { position: relative; min-height: 90vh; display: flex; align-items: center; justify-content: center; background: linear-gradient(135deg, #1a1a1a 0%, #212121 100%); overflow: hidden; text-align: center; padding: 6rem 2rem; } +.hero::before { content: ''; position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: radial-gradient(circle at 30% 50%, rgba(211, 47, 47, 0.15) 0%, transparent 50%); pointer-events: none; } +.hero .hero-content { position: relative; z-index: 2; max-width: 1000px; animation: fadeInUp 1s cubic-bezier(0.4, 0, 0.2, 1); } +.hero .hero-image { max-width: 500px; width: 100%; height: auto; margin-bottom: 3rem; filter: drop-shadow(0 10px 30px rgba(211, 47, 47, 0.3)); animation: float 6s ease-in-out infinite; } +@media (max-width: 768px) { .hero .hero-image { max-width: 300px; } } +.hero .hero-title { font-size: 4rem; color: #FFFFFF; margin-bottom: 1rem; font-weight: 700; text-shadow: 0 4px 8px rgba(0, 0, 0, 0.3); } +@media (max-width: 768px) { .hero .hero-title { font-size: 2.5rem; } } +.hero .hero-tagline { font-size: 1.5rem; color: #F5F5F5; margin-bottom: 3rem; font-weight: 300; } +@media (max-width: 768px) { .hero .hero-tagline { font-size: 1.125rem; } } +.hero .hero-buttons { display: flex; gap: 1rem; justify-content: center; flex-wrap: wrap; } + +.btn { display: inline-block; padding: 1rem 3rem; font-size: 1.125rem; font-weight: 500; text-decoration: none; border-radius: 8px; transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); cursor: pointer; border: 2px solid transparent; text-align: center; } +.btn.btn-primary { background: linear-gradient(135deg, #D32F2F 0%, #C62828 100%); color: #FFFFFF; box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2); } +.btn.btn-primary:hover { transform: translateY(-2px); box-shadow: 0 12px 24px rgba(0, 0, 0, 0.25); background: linear-gradient(135deg, #C62828 0%, #D32F2F 100%); } +.btn.btn-primary:active { transform: translateY(0); } +.btn.btn-secondary { background-color: transparent; color: #FFFFFF; border-color: #FFFFFF; } +.btn.btn-secondary:hover { background-color: #FFFFFF; color: #D32F2F; transform: translateY(-2px); } +.btn.btn-ghost { background-color: transparent; color: #D32F2F; border-color: #D32F2F; } +.btn.btn-ghost:hover { background-color: #D32F2F; color: #FFFFFF; } + +.features .features-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 3rem; margin-top: 3rem; } + +.feature-card { background-color: #FFFFFF; padding: 3rem; border-radius: 12px; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15); transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); border: 2px solid transparent; } +.feature-card:hover { transform: translateY(-8px); box-shadow: 0 12px 24px rgba(0, 0, 0, 0.25); border-color: #D32F2F; } +.feature-card .feature-icon { font-size: 3rem; color: #D32F2F; margin-bottom: 1rem; display: block; } +.feature-card .feature-title { font-size: 1.75rem; color: #212121; margin-bottom: 1rem; } +.feature-card .feature-description { color: #424242; line-height: 1.7; } + +.section-header { text-align: center; margin-bottom: 6rem; } +.section-header .section-title { font-size: 2.5rem; color: #212121; margin-bottom: 1rem; } +.section-dark .section-header .section-title { color: #FFFFFF; } +.section-header .section-subtitle { font-size: 1.25rem; color: #424242; font-weight: 300; max-width: 700px; margin: 0 auto; } +.section-dark .section-header .section-subtitle { color: #F5F5F5; } + +.overview { display: grid; grid-template-columns: 1fr 1fr; gap: 4rem; align-items: center; } +@media (max-width: 768px) { .overview { grid-template-columns: 1fr; gap: 3rem; } } +.overview .overview-content h3 { color: #FFFFFF; margin-bottom: 1rem; } +.overview .overview-content p { color: #F5F5F5; font-size: 1.125rem; line-height: 1.8; margin-bottom: 1rem; } +.overview .overview-image { text-align: center; } +.overview .overview-image img { max-width: 100%; height: auto; border-radius: 12px; box-shadow: 0 12px 24px rgba(0, 0, 0, 0.25); } + +.requirements-list { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 2rem; margin-top: 3rem; } +.requirements-list .requirement-item { display: flex; align-items: center; gap: 1rem; padding: 2rem 1rem; background-color: #FFFFFF; border-radius: 8px; border-left: 4px solid #D32F2F; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); } +.requirements-list .requirement-item:hover { box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15); transform: translateY(-2px); } +.requirements-list .requirement-item .requirement-icon { color: #D32F2F; font-size: 1.5rem; flex-shrink: 0; font-weight: bold; } +.requirements-list .requirement-item .requirement-text { color: #212121; font-size: 1rem; line-height: 1.5; } + +.doc-card { background-color: #FFFFFF; border-radius: 12px; padding: 6rem; margin-bottom: 3rem; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); border-left: 4px solid #D32F2F; line-height: 1.8; } +@media (max-width: 768px) { .doc-card { padding: 3rem; } } +.doc-card h1 { color: #212121; font-size: 2.5rem; margin-bottom: 3rem; padding-bottom: 1rem; border-bottom: 2px solid #F5F5F5; } +@media (max-width: 768px) { .doc-card h1 { font-size: 2rem; } } +.doc-card h2 { color: #212121; font-size: 1.875rem; margin-top: 6rem; margin-bottom: 2rem; padding-top: 2rem; } +@media (max-width: 768px) { .doc-card h2 { font-size: 1.5rem; margin-top: 3rem; } } +.doc-card h3 { color: #212121; font-size: 1.5rem; margin-top: 3rem; margin-bottom: 1rem; } +@media (max-width: 768px) { .doc-card h3 { font-size: 1.25rem; } } +.doc-card h4 { color: #424242; font-size: 1.25rem; margin-top: 2rem; margin-bottom: 1rem; font-weight: 500; } +.doc-card p { margin-bottom: 2rem; color: #212121; font-size: 1.0625rem; line-height: 1.8; } +.doc-card ul, .doc-card ol { margin-bottom: 2rem; margin-left: 2rem; } +.doc-card ul li, .doc-card ol li { margin-bottom: 0.5rem; color: #212121; font-size: 1.0625rem; line-height: 1.7; } +.doc-card table { width: 100%; border-collapse: collapse; margin: 3rem 0; font-size: 0.9375rem; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); border-radius: 8px; overflow: hidden; } +.doc-card table thead { background-color: #212121; color: #FFFFFF; } +.doc-card table thead th { padding: 1rem 2rem; text-align: left; font-weight: 500; border-bottom: 2px solid #D32F2F; } +.doc-card table tbody tr { border-bottom: 1px solid #F5F5F5; } +.doc-card table tbody tr:nth-child(even) { background-color: #fafafa; } +.doc-card table tbody tr:hover { background-color: rgba(211, 47, 47, 0.05); } +.doc-card table tbody td { padding: 1rem 2rem; color: #212121; } +.doc-card table tbody td code { background-color: rgba(211, 47, 47, 0.1); color: #C62828; padding: 2px 6px; border-radius: 3px; font-size: 0.875em; } +.doc-card pre { background-color: #f8f8f8; border: 1px solid #e0e0e0; border-left: 4px solid #D32F2F; border-radius: 8px; padding: 2rem; overflow-x: auto; margin: 2rem 0; font-size: 0.9rem; line-height: 1.6; } +.doc-card pre code { background-color: transparent; color: #212121; font-family: "Consolas", "Monaco", "Courier New", monospace; } +.doc-card code { background-color: rgba(211, 47, 47, 0.1); color: #C62828; padding: 2px 6px; border-radius: 3px; font-size: 0.9em; font-family: "Consolas", "Monaco", "Courier New", monospace; } +.doc-card blockquote { border-left: 4px solid #D32F2F; padding-left: 2rem; margin: 2rem 0; color: #424242; font-style: italic; } +.doc-card a { color: #D32F2F; text-decoration: none; font-weight: 500; transition: color 0.3s cubic-bezier(0.4, 0, 0.2, 1); } +.doc-card a:hover { color: #C62828; text-decoration: underline; } +.doc-card hr { border: none; border-top: 2px solid #F5F5F5; margin: 6rem 0; } +.doc-card .doc-meta { color: #424242; font-size: 0.875rem; margin-bottom: 3rem; padding-bottom: 2rem; border-bottom: 1px solid #F5F5F5; } + +@keyframes fadeInUp { from { opacity: 0; transform: translateY(30px); } + to { opacity: 1; transform: translateY(0); } } +@keyframes float { 0%, 100% { transform: translateY(0px); } + 50% { transform: translateY(-20px); } } +.text-center { text-align: center; } + +.mt-0 { margin-top: 0; } + +.mt-1 { margin-top: 0.5rem; } + +.mt-2 { margin-top: 1rem; } + +.mt-3 { margin-top: 2rem; } + +.mt-4 { margin-top: 3rem; } + +.mb-0 { margin-bottom: 0; } + +.mb-1 { margin-bottom: 0.5rem; } + +.mb-2 { margin-bottom: 1rem; } + +.mb-3 { margin-bottom: 2rem; } + +.mb-4 { margin-bottom: 3rem; } + +.doc-layout { display: grid; grid-template-columns: 260px 1fr; gap: 6rem; align-items: start; position: relative; } +@media (max-width: 1024px) and (min-width: 768px) { .doc-layout { grid-template-columns: 220px 1fr; gap: 3rem; } } +@media (max-width: 768px) { .doc-layout { grid-template-columns: 1fr; gap: 0; } } + +.doc-sidebar { position: sticky; top: 90px; max-height: calc(100vh - 120px); overflow-y: auto; } +@media (max-width: 768px) { .doc-sidebar { position: fixed; top: 70px; left: -100%; width: 280px; max-width: 85vw; height: calc(100vh - 70px); background-color: rgba(26, 26, 26, 0.95); backdrop-filter: blur(10px); z-index: 999; padding: 2rem; transition: left 0.3s cubic-bezier(0.4, 0, 0.2, 1); overflow-y: auto; box-shadow: 0 12px 24px rgba(0, 0, 0, 0.25); } + .doc-sidebar.mobile-open { left: 0; } } +.doc-sidebar::-webkit-scrollbar { width: 6px; } +.doc-sidebar::-webkit-scrollbar-track { background: transparent; } +.doc-sidebar::-webkit-scrollbar-thumb { background: rgba(66, 66, 66, 0.3); border-radius: 3px; } +.doc-sidebar::-webkit-scrollbar-thumb:hover { background: rgba(66, 66, 66, 0.5); } + +.doc-main { min-width: 0; max-width: 900px; } +@media (max-width: 1024px) { .doc-main { max-width: 100%; } } + +.doc-toc-mobile-toggle { display: none; } +@media (max-width: 768px) { .doc-toc-mobile-toggle { display: flex; align-items: center; justify-content: center; gap: 0.5rem; width: 100%; padding: 1rem 2rem; background: linear-gradient(135deg, #D32F2F 0%, #C62828 100%); color: #FFFFFF; border: none; border-radius: 8px; font-weight: 500; font-size: 1rem; cursor: pointer; margin-bottom: 2rem; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15); transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); } + .doc-toc-mobile-toggle:hover { transform: translateY(-2px); box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2); } + .doc-toc-mobile-toggle:active { transform: translateY(0); } + .doc-toc-mobile-toggle span { display: flex; align-items: center; gap: 0.5rem; } } + +.doc-toc { background-color: #FFFFFF; border-radius: 12px; padding: 2rem; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); border-left: 4px solid #D32F2F; } +@media (max-width: 768px) { .doc-toc { background-color: #212121; border-left-color: #FF5252; } } +.doc-toc .doc-toc-header { margin-bottom: 2rem; padding-bottom: 1rem; border-bottom: 2px solid #F5F5F5; } +@media (max-width: 768px) { .doc-toc .doc-toc-header { border-bottom-color: #424242; } } +.doc-toc .doc-toc-header h3 { font-size: 0.875rem; font-weight: 700; color: #212121; margin: 0; text-transform: uppercase; letter-spacing: 0.5px; } +@media (max-width: 768px) { .doc-toc .doc-toc-header h3 { color: #FFFFFF; } } +.doc-toc .doc-toc-list { list-style: none; padding: 0; margin: 0; } +.doc-toc .doc-toc-list li { margin-bottom: 0.5rem; } +.doc-toc .doc-toc-list .toc-link { display: block; padding: 0.5rem 1rem; color: #424242; text-decoration: none; border-radius: 8px; transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); font-size: 0.9375rem; line-height: 1.5; border-left: 3px solid transparent; } +@media (max-width: 768px) { .doc-toc .doc-toc-list .toc-link { color: #F5F5F5; font-size: 1rem; padding: 1rem; } } +.doc-toc .doc-toc-list .toc-link:hover { color: #D32F2F; background-color: rgba(211, 47, 47, 0.1); border-left-color: #D32F2F; padding-left: calc($spacing-sm + 3px); } +@media (max-width: 768px) { .doc-toc .doc-toc-list .toc-link:hover { color: #FF5252; background-color: rgba(255, 82, 82, 0.15); } } +.doc-toc .doc-toc-list .toc-link.active { color: #D32F2F; background-color: rgba(211, 47, 47, 0.15); border-left-color: #D32F2F; font-weight: 500; padding-left: calc($spacing-sm + 3px); } +@media (max-width: 768px) { .doc-toc .doc-toc-list .toc-link.active { color: #FF5252; background-color: rgba(255, 82, 82, 0.2); border-left-color: #FF5252; } } + +@media (max-width: 768px) { .doc-sidebar.mobile-open::before { content: ''; position: fixed; top: 70px; left: 0; right: 0; bottom: 0; background-color: rgba(26, 26, 26, 0.5); z-index: -1; } } +.doc-download-section { display: flex; gap: 1rem; margin-bottom: 3rem; padding-bottom: 3rem; border-bottom: 2px solid #F5F5F5; flex-wrap: wrap; } +@media (max-width: 480px) { .doc-download-section { flex-direction: column; } } + +.btn-download-pdf { display: inline-flex; align-items: center; gap: 0.5rem; padding: 1rem 2rem; background-color: #FFFFFF; color: #D32F2F; border: 2px solid #D32F2F; border-radius: 8px; text-decoration: none; font-weight: 500; font-size: 0.9375rem; transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); } +.btn-download-pdf svg { flex-shrink: 0; } +.btn-download-pdf:hover { background-color: #D32F2F; color: #FFFFFF; transform: translateY(-2px); box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15); } +.btn-download-pdf:hover svg { animation: downloadBounce 0.6s ease-in-out; } +.btn-download-pdf:active { transform: translateY(0); } +.btn-download-pdf.btn-download-complete { background-color: #D32F2F; color: #FFFFFF; } +.btn-download-pdf.btn-download-complete:hover { background-color: #C62828; } +@media (max-width: 480px) { .btn-download-pdf { justify-content: center; width: 100%; } } + +@keyframes downloadBounce { 0%, 100% { transform: translateY(0); } + 50% { transform: translateY(3px); } } +.alert { padding: 2rem 3rem; border-radius: 8px; margin: 3rem 0; border-left: 4px solid; } +.alert.alert-warning { background-color: #fff3cd; border-left-color: #ffc107; color: #856404; } +.alert.alert-warning strong { color: #856404; } +.alert.alert-info { background-color: #d1ecf1; border-left-color: #17a2b8; color: #0c5460; } +.alert.alert-info strong { color: #0c5460; } +.alert.alert-danger { background-color: #f8d7da; border-left-color: #dc3545; color: #721c24; } +.alert.alert-danger strong { color: #721c24; } +.alert.alert-success { background-color: #d4edda; border-left-color: #28a745; color: #155724; } +.alert.alert-success strong { color: #155724; } +.alert p:last-child { margin-bottom: 0; } diff --git a/gh_pages/_site/assets/images/Camera_Hero_NoBackground.png b/gh_pages/_site/assets/images/Camera_Hero_NoBackground.png new file mode 100644 index 0000000..c8d1146 Binary files /dev/null and b/gh_pages/_site/assets/images/Camera_Hero_NoBackground.png differ diff --git a/gh_pages/_site/assets/js/main.js b/gh_pages/_site/assets/js/main.js new file mode 100644 index 0000000..8b0ae96 --- /dev/null +++ b/gh_pages/_site/assets/js/main.js @@ -0,0 +1,107 @@ +// Mobile Menu Toggle +document.addEventListener('DOMContentLoaded', function() { + const mobileMenuToggle = document.querySelector('.mobile-menu-toggle'); + const siteNav = document.querySelector('.site-nav'); + + if (mobileMenuToggle) { + mobileMenuToggle.addEventListener('click', function() { + siteNav.classList.toggle('active'); + this.innerHTML = siteNav.classList.contains('active') ? '✕' : '☰'; + }); + + // Close menu when clicking a link + const navLinks = document.querySelectorAll('.site-nav a'); + navLinks.forEach(link => { + link.addEventListener('click', function() { + siteNav.classList.remove('active'); + mobileMenuToggle.innerHTML = '☰'; + }); + }); + + // Close menu when clicking outside + document.addEventListener('click', function(event) { + if (!siteNav.contains(event.target) && !mobileMenuToggle.contains(event.target)) { + siteNav.classList.remove('active'); + mobileMenuToggle.innerHTML = '☰'; + } + }); + } + + // Smooth scroll for anchor links + document.querySelectorAll('a[href^="#"]').forEach(anchor => { + anchor.addEventListener('click', function (e) { + const href = this.getAttribute('href'); + if (href !== '#') { + e.preventDefault(); + const target = document.querySelector(href); + if (target) { + const offsetTop = target.offsetTop - 70; // Account for fixed header + window.scrollTo({ + top: offsetTop, + behavior: 'smooth' + }); + } + } + }); + }); + + // Header shadow on scroll + const header = document.querySelector('.site-header'); + let lastScrollTop = 0; + + window.addEventListener('scroll', function() { + const scrollTop = window.pageYOffset || document.documentElement.scrollTop; + + if (scrollTop > 50) { + header.style.boxShadow = '0 4px 12px rgba(0, 0, 0, 0.3)'; + } else { + header.style.boxShadow = '0 2px 8px rgba(0, 0, 0, 0.15)'; + } + + lastScrollTop = scrollTop; + }); + + // Fade in elements on scroll + const observerOptions = { + threshold: 0.1, + rootMargin: '0px 0px -50px 0px' + }; + + const observer = new IntersectionObserver(function(entries) { + entries.forEach(entry => { + if (entry.isIntersecting) { + entry.target.style.opacity = '1'; + entry.target.style.transform = 'translateY(0)'; + } + }); + }, observerOptions); + + // Observe feature cards and other elements + const animatedElements = document.querySelectorAll('.feature-card, .overview, .requirement-item'); + animatedElements.forEach(el => { + el.style.opacity = '0'; + el.style.transform = 'translateY(30px)'; + el.style.transition = 'opacity 0.6s ease, transform 0.6s ease'; + observer.observe(el); + }); + + // Add loading animation complete + document.body.classList.add('loaded'); +}); + +// Copy code button for code blocks +document.querySelectorAll('pre code').forEach((block) => { + const button = document.createElement('button'); + button.className = 'copy-code-btn'; + button.textContent = 'Copy'; + button.addEventListener('click', () => { + navigator.clipboard.writeText(block.textContent).then(() => { + button.textContent = 'Copied!'; + setTimeout(() => { + button.textContent = 'Copy'; + }, 2000); + }); + }); + block.parentElement.style.position = 'relative'; + block.parentElement.appendChild(button); +}); diff --git a/gh_pages/_site/assets/main.css b/gh_pages/_site/assets/main.css new file mode 100644 index 0000000..83b9124 --- /dev/null +++ b/gh_pages/_site/assets/main.css @@ -0,0 +1,196 @@ +/** Reset some basic elements */ +body, h1, h2, h3, h4, h5, h6, p, blockquote, pre, hr, dl, dd, ol, ul, figure { margin: 0; padding: 0; } + +/** Basic styling */ +body { font: 400 16px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; color: #111; background-color: #fdfdfd; -webkit-text-size-adjust: 100%; -webkit-font-feature-settings: "kern" 1; -moz-font-feature-settings: "kern" 1; -o-font-feature-settings: "kern" 1; font-feature-settings: "kern" 1; font-kerning: normal; display: flex; min-height: 100vh; flex-direction: column; } + +/** Set `margin-bottom` to maintain vertical rhythm */ +h1, h2, h3, h4, h5, h6, p, blockquote, pre, ul, ol, dl, figure, .highlight { margin-bottom: 15px; } + +/** `main` element */ +main { display: block; /* Default value of `display` of `main` element is 'inline' in IE 11. */ } + +/** Images */ +img { max-width: 100%; vertical-align: middle; } + +/** Figures */ +figure > img { display: block; } + +figcaption { font-size: 14px; } + +/** Lists */ +ul, ol { margin-left: 30px; } + +li > ul, li > ol { margin-bottom: 0; } + +/** Headings */ +h1, h2, h3, h4, h5, h6 { font-weight: 400; } + +/** Links */ +a { color: #2a7ae2; text-decoration: none; } +a:visited { color: #1756a9; } +a:hover { color: #111; text-decoration: underline; } +.social-media-list a:hover { text-decoration: none; } +.social-media-list a:hover .username { text-decoration: underline; } + +/** Blockquotes */ +blockquote { color: #828282; border-left: 4px solid #e8e8e8; padding-left: 15px; font-size: 18px; letter-spacing: -1px; font-style: italic; } +blockquote > :last-child { margin-bottom: 0; } + +/** Code formatting */ +pre, code { font-size: 15px; border: 1px solid #e8e8e8; border-radius: 3px; background-color: #eef; } + +code { padding: 1px 5px; } + +pre { padding: 8px 12px; overflow-x: auto; } +pre > code { border: 0; padding-right: 0; padding-left: 0; } + +/** Wrapper */ +.wrapper { max-width: -webkit-calc(800px - (30px * 2)); max-width: calc(800px - (30px * 2)); margin-right: auto; margin-left: auto; padding-right: 30px; padding-left: 30px; } +@media screen and (max-width: 800px) { .wrapper { max-width: -webkit-calc(800px - (30px)); max-width: calc(800px - (30px)); padding-right: 15px; padding-left: 15px; } } + +/** Clearfix */ +.wrapper:after, .footer-col-wrapper:after { content: ""; display: table; clear: both; } + +/** Icons */ +.svg-icon { width: 16px; height: 16px; display: inline-block; fill: #828282; padding-right: 5px; vertical-align: text-top; } + +.social-media-list li + li { padding-top: 5px; } + +/** Tables */ +table { margin-bottom: 30px; width: 100%; text-align: left; color: #3f3f3f; border-collapse: collapse; border: 1px solid #e8e8e8; } +table tr:nth-child(even) { background-color: #f7f7f7; } +table th, table td { padding: 10px 15px; } +table th { background-color: #f0f0f0; border: 1px solid #dedede; border-bottom-color: #c9c9c9; } +table td { border: 1px solid #e8e8e8; } + +/** Site header */ +.site-header { border-top: 5px solid #424242; border-bottom: 1px solid #e8e8e8; min-height: 55.95px; position: relative; } + +.site-title { font-size: 26px; font-weight: 300; line-height: 54px; letter-spacing: -1px; margin-bottom: 0; float: left; } +.site-title, .site-title:visited { color: #424242; } + +.site-nav { float: right; line-height: 54px; } +.site-nav .nav-trigger { display: none; } +.site-nav .menu-icon { display: none; } +.site-nav .page-link { color: #111; line-height: 1.5; } +.site-nav .page-link:not(:last-child) { margin-right: 20px; } +@media screen and (max-width: 600px) { .site-nav { position: absolute; top: 9px; right: 15px; background-color: #fdfdfd; border: 1px solid #e8e8e8; border-radius: 5px; text-align: right; } + .site-nav label[for="nav-trigger"] { display: block; float: right; width: 36px; height: 36px; z-index: 2; cursor: pointer; } + .site-nav .menu-icon { display: block; float: right; width: 36px; height: 26px; line-height: 0; padding-top: 10px; text-align: center; } + .site-nav .menu-icon > svg { fill: #424242; } + .site-nav input ~ .trigger { clear: both; display: none; } + .site-nav input:checked ~ .trigger { display: block; padding-bottom: 5px; } + .site-nav .page-link { display: block; padding: 5px 10px; margin-left: 20px; } + .site-nav .page-link:not(:last-child) { margin-right: 0; } } + +/** Site footer */ +.site-footer { border-top: 1px solid #e8e8e8; padding: 30px 0; } + +.footer-heading { font-size: 18px; margin-bottom: 15px; } + +.contact-list, .social-media-list { list-style: none; margin-left: 0; } + +.footer-col-wrapper { font-size: 15px; color: #828282; margin-left: -15px; } + +.footer-col { float: left; margin-bottom: 15px; padding-left: 15px; } + +.footer-col-1 { width: -webkit-calc(35% - (30px / 2)); width: calc(35% - (30px / 2)); } + +.footer-col-2 { width: -webkit-calc(20% - (30px / 2)); width: calc(20% - (30px / 2)); } + +.footer-col-3 { width: -webkit-calc(45% - (30px / 2)); width: calc(45% - (30px / 2)); } + +@media screen and (max-width: 800px) { .footer-col-1, .footer-col-2 { width: -webkit-calc(50% - (30px / 2)); width: calc(50% - (30px / 2)); } + .footer-col-3 { width: -webkit-calc(100% - (30px / 2)); width: calc(100% - (30px / 2)); } } +@media screen and (max-width: 600px) { .footer-col { float: none; width: -webkit-calc(100% - (30px / 2)); width: calc(100% - (30px / 2)); } } +/** Page content */ +.page-content { padding: 30px 0; flex: 1; } + +.page-heading { font-size: 32px; } + +.post-list-heading { font-size: 28px; } + +.post-list { margin-left: 0; list-style: none; } +.post-list > li { margin-bottom: 30px; } + +.post-meta { font-size: 14px; color: #828282; } + +.post-link { display: block; font-size: 24px; } + +/** Posts */ +.post-header { margin-bottom: 30px; } + +.post-title { font-size: 42px; letter-spacing: -1px; line-height: 1; } +@media screen and (max-width: 800px) { .post-title { font-size: 36px; } } + +.post-content { margin-bottom: 30px; } +.post-content h2 { font-size: 32px; } +@media screen and (max-width: 800px) { .post-content h2 { font-size: 28px; } } +.post-content h3 { font-size: 26px; } +@media screen and (max-width: 800px) { .post-content h3 { font-size: 22px; } } +.post-content h4 { font-size: 20px; } +@media screen and (max-width: 800px) { .post-content h4 { font-size: 18px; } } + +/** Syntax highlighting styles */ +.highlight { background: #fff; } +.highlighter-rouge .highlight { background: #eef; } +.highlight .c { color: #998; font-style: italic; } +.highlight .err { color: #a61717; background-color: #e3d2d2; } +.highlight .k { font-weight: bold; } +.highlight .o { font-weight: bold; } +.highlight .cm { color: #998; font-style: italic; } +.highlight .cp { color: #999; font-weight: bold; } +.highlight .c1 { color: #998; font-style: italic; } +.highlight .cs { color: #999; font-weight: bold; font-style: italic; } +.highlight .gd { color: #000; background-color: #fdd; } +.highlight .gd .x { color: #000; background-color: #faa; } +.highlight .ge { font-style: italic; } +.highlight .gr { color: #a00; } +.highlight .gh { color: #999; } +.highlight .gi { color: #000; background-color: #dfd; } +.highlight .gi .x { color: #000; background-color: #afa; } +.highlight .go { color: #888; } +.highlight .gp { color: #555; } +.highlight .gs { font-weight: bold; } +.highlight .gu { color: #aaa; } +.highlight .gt { color: #a00; } +.highlight .kc { font-weight: bold; } +.highlight .kd { font-weight: bold; } +.highlight .kp { font-weight: bold; } +.highlight .kr { font-weight: bold; } +.highlight .kt { color: #458; font-weight: bold; } +.highlight .m { color: #099; } +.highlight .s { color: #d14; } +.highlight .na { color: #008080; } +.highlight .nb { color: #0086B3; } +.highlight .nc { color: #458; font-weight: bold; } +.highlight .no { color: #008080; } +.highlight .ni { color: #800080; } +.highlight .ne { color: #900; font-weight: bold; } +.highlight .nf { color: #900; font-weight: bold; } +.highlight .nn { color: #555; } +.highlight .nt { color: #000080; } +.highlight .nv { color: #008080; } +.highlight .ow { font-weight: bold; } +.highlight .w { color: #bbb; } +.highlight .mf { color: #099; } +.highlight .mh { color: #099; } +.highlight .mi { color: #099; } +.highlight .mo { color: #099; } +.highlight .sb { color: #d14; } +.highlight .sc { color: #d14; } +.highlight .sd { color: #d14; } +.highlight .s2 { color: #d14; } +.highlight .se { color: #d14; } +.highlight .sh { color: #d14; } +.highlight .si { color: #d14; } +.highlight .sx { color: #d14; } +.highlight .sr { color: #009926; } +.highlight .s1 { color: #d14; } +.highlight .ss { color: #990073; } +.highlight .bp { color: #999; } +.highlight .vc { color: #008080; } +.highlight .vg { color: #008080; } +.highlight .vi { color: #008080; } +.highlight .il { color: #099; } diff --git a/gh_pages/_site/assets/minima-social-icons.svg b/gh_pages/_site/assets/minima-social-icons.svg new file mode 100644 index 0000000..fa7399f --- /dev/null +++ b/gh_pages/_site/assets/minima-social-icons.svg @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gh_pages/_site/assets/pdf-template/template.tex b/gh_pages/_site/assets/pdf-template/template.tex new file mode 100644 index 0000000..21525bd --- /dev/null +++ b/gh_pages/_site/assets/pdf-template/template.tex @@ -0,0 +1,163 @@ +% Event Video Playback Documentation Template +\documentclass[$if(fontsize)$$fontsize$,$endif$$if(lang)$$babel-lang$,$endif$$if(papersize)$$papersize$paper,$endif$$for(classoption)$$classoption$$sep$,$endfor$]{$documentclass$} + +% Packages +\usepackage{lmodern} +\usepackage{amssymb,amsmath} +\usepackage{ifxetex,ifluatex} +\usepackage{fixltx2e} +\usepackage[T1]{fontenc} +\usepackage[utf8]{inputenc} +\usepackage{microtype} +\usepackage[$for(geometry)$$geometry$$sep$,$endfor$]{geometry} +\usepackage{hyperref} +\usepackage{graphicx} +\usepackage{grffile} +\usepackage{longtable,booktabs} +\usepackage{listings} +\usepackage{fancyhdr} +\usepackage{lastpage} +\usepackage{xcolor} + +% Define colors (matching website theme) +\definecolor{primaryred}{RGB}{211,47,47} +\definecolor{darkred}{RGB}{198,40,40} +\definecolor{darkgray}{RGB}{33,33,33} +\definecolor{lightgray}{RGB}{245,245,245} +\definecolor{codebg}{RGB}{248,248,248} + +% Hyperref setup +\hypersetup{ + breaklinks=true, + bookmarks=true, + pdfauthor={$author-meta$}, + pdftitle={$title-meta$}, + colorlinks=true, + linkcolor=$if(linkcolor)$$linkcolor$$else$primaryred$endif$, + citecolor=$if(citecolor)$$citecolor$$else$blue$endif$, + urlcolor=$if(urlcolor)$$urlcolor$$else$primaryred$endif$, + pdfborder={0 0 0} +} + +% Headers and Footers +\pagestyle{fancy} +\fancyhf{} +\fancyhead[L]{\small\textcolor{darkgray}{$title$}} +\fancyhead[R]{\small\textcolor{darkgray}{Beckhoff USA Community}} +\fancyfoot[C]{\small\textcolor{darkgray}{Page \thepage\ of \pageref{LastPage}}} +\renewcommand{\headrulewidth}{0.5pt} +\renewcommand{\footrulewidth}{0.5pt} +\renewcommand{\headrule}{\hbox to\headwidth{\color{primaryred}\leaders\hrule height \headrulewidth\hfill}} +\renewcommand{\footrule}{\hbox to\headwidth{\color{primaryred}\leaders\hrule height \footrulewidth\hfill}} + +% Title formatting +\usepackage{titling} +\pretitle{\begin{center}\LARGE\bfseries\color{primaryred}} +\posttitle{\par\end{center}\vskip 0.5em} +\preauthor{\begin{center}\large\color{darkgray}} +\postauthor{\end{center}} +\predate{\begin{center}\large\color{darkgray}} +\postdate{\par\end{center}} + +% Section formatting +\usepackage{titlesec} +\titleformat{\section} + {\Large\bfseries\color{primaryred}} + {\thesection}{1em}{} +\titleformat{\subsection} + {\large\bfseries\color{darkgray}} + {\thesubsection}{1em}{} +\titleformat{\subsubsection} + {\normalsize\bfseries\color{darkgray}} + {\thesubsubsection}{1em}{} + +% Code listings +\lstset{ + backgroundcolor=\color{codebg}, + basicstyle=\small\ttfamily, + breaklines=true, + captionpos=b, + commentstyle=\color{darkgray}, + frame=single, + frameround=tttt, + rulecolor=\color{primaryred}, + keywordstyle=\color{primaryred}, + numbers=left, + numberstyle=\tiny\color{darkgray}, + stringstyle=\color{darkred}, + tabsize=2, + xleftmargin=2em, + framexleftmargin=1.5em +} + +% Inline code +\usepackage{listings} +\lstdefinestyle{inlinecode}{ + basicstyle=\ttfamily\small, + backgroundcolor=\color{codebg}, + breaklines=false +} + +% Table styling +\usepackage{array} +\usepackage{colortbl} +\arrayrulecolor{primaryred} +\renewcommand{\arraystretch}{1.2} + +% Pandoc compatibility +$if(highlighting-macros)$ +$highlighting-macros$ +$endif$ + +% Document metadata +$if(title)$ +\title{$title$} +$endif$ +$if(author)$ +\author{$for(author)$$author$$sep$ \and $endfor$} +$endif$ +$if(date)$ +\date{$date$} +$endif$ + +% Begin document +\begin{document} + +% Title page +$if(title)$ +\maketitle +$endif$ + +% Abstract +$if(abstract)$ +\begin{abstract} +$abstract$ +\end{abstract} +$endif$ + +% Table of contents +$if(toc)$ +{ +\hypersetup{linkcolor=black} +\setcounter{tocdepth}{$toc-depth$} +\tableofcontents +} +\newpage +$endif$ + +% Body +$body$ + +% Back matter +\vfill +\begin{center} +\color{darkgray} +\rule{0.5\textwidth}{0.4pt}\\[0.5em] +\small +Generated from Event Video Playback Documentation\\ +\textcopyright\ Beckhoff USA Community\\ +Licensed under MIT License\\ +\url{https://github.com/Beckhoff-USA-Community/EventVideoPlayback} +\end{center} + +\end{document} diff --git a/gh_pages/_site/assets/pdf/README.md b/gh_pages/_site/assets/pdf/README.md new file mode 100644 index 0000000..e8b5510 --- /dev/null +++ b/gh_pages/_site/assets/pdf/README.md @@ -0,0 +1,155 @@ +# Documentation PDF Generation + +This directory contains auto-generated PDF versions of the Event Video Playback documentation. + +## 📄 Available PDFs + +The following PDFs are automatically generated from the markdown documentation: + +- **getting-started.pdf** - Installation and setup guide +- **plc-usage.pdf** - PLC library documentation +- **service-config.pdf** - Service configuration guide +- **hmi-usage.pdf** - HMI NuGet package guide +- **complete-documentation.pdf** - All documentation in one PDF + +## 🔄 How PDF Generation Works + +PDFs are automatically generated using **GitHub Actions** whenever documentation changes are pushed. + +### Workflow Trigger + +The PDF generation workflow (`.github/workflows/generate-docs-pdf.yml`) runs when: +- Changes are pushed to `gh_pages/_docs/` directory +- Changes are pushed to the PDF template +- Workflow is manually triggered via GitHub Actions UI + +### Generation Process + +1. **Pandoc** converts markdown files to PDF +2. Custom **LaTeX template** applies Event Video Playback branding (red/black theme) +3. PDFs include: + - Professional formatting + - Table of contents + - Headers and footers + - Color-coded links + - Code syntax highlighting + - Page numbers +4. Generated PDFs are committed back to this directory +5. PDFs become available for download on the website + +## 🎨 PDF Styling + +PDFs use a custom LaTeX template (`assets/pdf-template/template.tex`) that: +- Matches the website's red/black color scheme +- Uses primary red (#D32F2F) for headings and links +- Includes Beckhoff USA Community branding +- Provides professional headers and footers +- Formats code blocks with syntax highlighting + +## 🚀 Manual Workflow Trigger + +To manually regenerate PDFs: + +1. Go to **GitHub Actions** tab +2. Select **"Generate Documentation PDFs"** workflow +3. Click **"Run workflow"** +4. Choose branch (main or v2.0.0) +5. Click **"Run workflow"** button + +PDFs will be generated and committed within 2-3 minutes. + +## 📥 Download Buttons + +Each documentation page includes two download buttons: + +1. **"Download as PDF"** - Downloads the current page as PDF +2. **"Download Complete Docs"** - Downloads all documentation combined + +Buttons are styled with: +- White background with red border (current page) +- Red background with white text (complete docs) +- Hover animations +- Download icons from Feather Icons + +## 🔧 Customizing PDF Output + +### Modify Template + +Edit `assets/pdf-template/template.tex` to customize: +- Colors and branding +- Page layout and margins +- Header/footer content +- Font sizes and styles +- Code block styling + +### Modify Workflow + +Edit `.github/workflows/generate-docs-pdf.yml` to: +- Change Pandoc options +- Add/remove PDFs +- Adjust metadata (title, author, date) +- Configure PDF settings + +### Example: Change Margins + +In the workflow, modify the `--variable geometry:margin=` option: + +```yaml +--variable geometry:margin=1.5in # Larger margins +--variable geometry:margin=0.75in # Smaller margins +``` + +### Example: Change Font Size + +```yaml +--variable fontsize=12pt # Larger text +--variable fontsize=10pt # Smaller text +``` + +## 🐛 Troubleshooting + +### PDFs Not Generating + +1. Check GitHub Actions workflow status +2. Review workflow logs for errors +3. Ensure markdown syntax is valid +4. Verify LaTeX template syntax + +### PDF Formatting Issues + +- **Tables not displaying correctly**: Simplify table structure or use smaller font +- **Code blocks overflowing**: Use `breaklines=true` in listings settings +- **Links not working**: Ensure URLs are properly formatted in markdown + +### Force Regeneration + +If PDFs appear outdated: + +1. Make a small change to any doc file (add a space) +2. Commit and push +3. Workflow will run automatically + +Or trigger manually via GitHub Actions UI. + +## 📦 Dependencies + +The workflow requires: +- **Pandoc** - Document converter +- **LaTeX** (texlive) - PDF rendering engine +- Includes: texlive-latex-base, texlive-fonts-recommended, texlive-fonts-extra, texlive-latex-extra + +These are automatically installed by the GitHub Actions runner. + +## 📝 Notes + +- PDFs are committed with `[skip ci]` message to avoid infinite workflow loops +- Generated PDFs are tracked in git for easy access +- File sizes: ~100-500KB per PDF (depending on content) +- Generation time: ~30-60 seconds per PDF + +## 🔗 Links + +- [GitHub Actions Workflows](../../.github/workflows/) +- [PDF Template](../pdf-template/template.tex) +- [Documentation Source](_docs/) +- [Live Website](https://beckhoff-usa-community.github.io/EventVideoPlayback/) diff --git a/gh_pages/_site/assets/pdf/index.html b/gh_pages/_site/assets/pdf/index.html new file mode 100644 index 0000000..82285cc --- /dev/null +++ b/gh_pages/_site/assets/pdf/index.html @@ -0,0 +1,298 @@ + + + + + + + + Documentation PDF Generation | Event Video Playback + + + + + +Documentation PDF Generation | Event Video Playback + + + + + + + + + + + + + + + + + + + +
+
+ +
+

Documentation PDF Generation

+
+ +
+

Documentation PDF Generation

+ +

This directory contains auto-generated PDF versions of the Event Video Playback documentation.

+ +

📄 Available PDFs

+ +

The following PDFs are automatically generated from the markdown documentation:

+ +
    +
  • getting-started.pdf - Installation and setup guide
  • +
  • plc-usage.pdf - PLC library documentation
  • +
  • service-config.pdf - Service configuration guide
  • +
  • hmi-usage.pdf - HMI NuGet package guide
  • +
  • complete-documentation.pdf - All documentation in one PDF
  • +
+ +

🔄 How PDF Generation Works

+ +

PDFs are automatically generated using GitHub Actions whenever documentation changes are pushed.

+ +

Workflow Trigger

+ +

The PDF generation workflow (.github/workflows/generate-docs-pdf.yml) runs when:

+
    +
  • Changes are pushed to gh_pages/_docs/ directory
  • +
  • Changes are pushed to the PDF template
  • +
  • Workflow is manually triggered via GitHub Actions UI
  • +
+ +

Generation Process

+ +
    +
  1. Pandoc converts markdown files to PDF
  2. +
  3. Custom LaTeX template applies Event Video Playback branding (red/black theme)
  4. +
  5. PDFs include: +
      +
    • Professional formatting
    • +
    • Table of contents
    • +
    • Headers and footers
    • +
    • Color-coded links
    • +
    • Code syntax highlighting
    • +
    • Page numbers
    • +
    +
  6. +
  7. Generated PDFs are committed back to this directory
  8. +
  9. PDFs become available for download on the website
  10. +
+ +

🎨 PDF Styling

+ +

PDFs use a custom LaTeX template (assets/pdf-template/template.tex) that:

+
    +
  • Matches the website’s red/black color scheme
  • +
  • Uses primary red (#D32F2F) for headings and links
  • +
  • Includes Beckhoff USA Community branding
  • +
  • Provides professional headers and footers
  • +
  • Formats code blocks with syntax highlighting
  • +
+ +

🚀 Manual Workflow Trigger

+ +

To manually regenerate PDFs:

+ +
    +
  1. Go to GitHub Actions tab
  2. +
  3. Select “Generate Documentation PDFs” workflow
  4. +
  5. Click “Run workflow”
  6. +
  7. Choose branch (main or v2.0.0)
  8. +
  9. Click “Run workflow” button
  10. +
+ +

PDFs will be generated and committed within 2-3 minutes.

+ +

📥 Download Buttons

+ +

Each documentation page includes two download buttons:

+ +
    +
  1. “Download as PDF” - Downloads the current page as PDF
  2. +
  3. “Download Complete Docs” - Downloads all documentation combined
  4. +
+ +

Buttons are styled with:

+
    +
  • White background with red border (current page)
  • +
  • Red background with white text (complete docs)
  • +
  • Hover animations
  • +
  • Download icons from Feather Icons
  • +
+ +

🔧 Customizing PDF Output

+ +

Modify Template

+ +

Edit assets/pdf-template/template.tex to customize:

+
    +
  • Colors and branding
  • +
  • Page layout and margins
  • +
  • Header/footer content
  • +
  • Font sizes and styles
  • +
  • Code block styling
  • +
+ +

Modify Workflow

+ +

Edit .github/workflows/generate-docs-pdf.yml to:

+
    +
  • Change Pandoc options
  • +
  • Add/remove PDFs
  • +
  • Adjust metadata (title, author, date)
  • +
  • Configure PDF settings
  • +
+ +

Example: Change Margins

+ +

In the workflow, modify the --variable geometry:margin= option:

+ +
--variable geometry:margin=1.5in  # Larger margins
+--variable geometry:margin=0.75in # Smaller margins
+
+ +

Example: Change Font Size

+ +
--variable fontsize=12pt  # Larger text
+--variable fontsize=10pt  # Smaller text
+
+ +

🐛 Troubleshooting

+ +

PDFs Not Generating

+ +
    +
  1. Check GitHub Actions workflow status
  2. +
  3. Review workflow logs for errors
  4. +
  5. Ensure markdown syntax is valid
  6. +
  7. Verify LaTeX template syntax
  8. +
+ +

PDF Formatting Issues

+ +
    +
  • Tables not displaying correctly: Simplify table structure or use smaller font
  • +
  • Code blocks overflowing: Use breaklines=true in listings settings
  • +
  • Links not working: Ensure URLs are properly formatted in markdown
  • +
+ +

Force Regeneration

+ +

If PDFs appear outdated:

+ +
    +
  1. Make a small change to any doc file (add a space)
  2. +
  3. Commit and push
  4. +
  5. Workflow will run automatically
  6. +
+ +

Or trigger manually via GitHub Actions UI.

+ +

📦 Dependencies

+ +

The workflow requires:

+
    +
  • Pandoc - Document converter
  • +
  • LaTeX (texlive) - PDF rendering engine
  • +
  • Includes: texlive-latex-base, texlive-fonts-recommended, texlive-fonts-extra, texlive-latex-extra
  • +
+ +

These are automatically installed by the GitHub Actions runner.

+ +

📝 Notes

+ +
    +
  • PDFs are committed with [skip ci] message to avoid infinite workflow loops
  • +
  • Generated PDFs are tracked in git for easy access
  • +
  • File sizes: ~100-500KB per PDF (depending on content)
  • +
  • Generation time: ~30-60 seconds per PDF
  • +
+ + + + + +
+ +
+ +
+ + + + + + + diff --git a/gh_pages/_site/docs/getting-started/index.html b/gh_pages/_site/docs/getting-started/index.html new file mode 100644 index 0000000..7b6f199 --- /dev/null +++ b/gh_pages/_site/docs/getting-started/index.html @@ -0,0 +1,459 @@ + + + + + + + + Getting Started | Event Video Playback + + + + + +Getting Started | Event Video Playback + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + +
+ + + + +
+
+ +

Getting Started

+ + + +

Learn how to install and configure Event Video Playback for your TwinCAT project

+ + + + + + + + + + +
+

Overview

+ +

Event Video Playback is a comprehensive solution for transforming TwinCAT Vision images into event-driven video recordings. This guide will walk you through the installation and initial setup process.

+ +

Prerequisites

+ +

Before you begin, ensure you have the following installed on your system:

+ +

For Engineering Development:

+
    +
  • Windows 10/11
  • +
  • TwinCAT Package Manager
  • +
  • TwinCAT 3.1 XAE Build 4026 or higher
  • +
  • TwinCAT Vision XAE 5.8.4 or higher
  • +
  • TwinCAT HMI XAE 14.9 or higher
  • +
+ +

For Runtime Targets:

+
    +
  • Windows 10/11
  • +
  • TwinCAT Package Manager
  • +
  • TwinCAT 3.1 XAR Build 4026 or higher
  • +
  • TwinCAT Vision XAR 5.8.4 or higher
  • +
+ +
+Warning: Previous versions of the 4024 Tc_EventVideoPlayback legacy project must be uninstalled before using the new 4026 build. +
+ +

TcPkg Package Signing Requirement

+ +

TwinCAT Package Manager only accepts officially signed packages from Beckhoff Automation GmbH & Co. KG by default. To use community packages, you need to temporarily disable signature verification. This applies to both locally hosted packages and remote packages; any 3rd party developed packages.

+ +
+ Security Notice: Disabling signature verification allows installation of third-party packages. Only use packages from trusted community sources. Review package contents and source code before installation. All community packages are provided "as is" without warranties. +
+ +

Run this command in PowerShell as Administrator to disable signature checks:

+
tcpkg config unset -n VerifySignatures
+
+ +

Installation Methods

+ +

Choose the installation method that best fits your environment:

+ + + +
+ +

Online Package Feed Connection

+ +

Best for: Systems with internet connectivity and access to the Beckhoff USA Community package feed.

+ +

Add Package Feed via GUI

+ +

If you haven’t already, add the Beckhoff USA Community package feed to TwinCAT Package Manager:

+ +
    +
  1. Open the TwinCAT Package Manager GUI
  2. +
  3. Click the Settings (Gear Icon) in the bottom left corner
  4. +
  5. Select Feeds
  6. +
+ +

For the feed settings use:

+
https://packages.beckhoff-usa-community.com/stable/v3/index.json
+
+

For the feed name use:

+
Beckhoff USA Community Stable
+
+

Deselect the Set credentials option, as we do not need login for the feed. Select Save and agree to the disclaimer to be connected.

+ +

Add Package Feed via Powershell

+ +
tcpkg source add -n "Beckhoff USA Community Stable" -s "https://packages.beckhoff-usa-community.com/stable/v3/index.json"
+
+

Agree to the disclaimer to be connected.

+ +
+ +

Offline Package Configuration

+ +

Best for: Air-gapped systems, manual installations, or when you need a specific version.

+ +
+ Tip: Instead of downloading the packages from the releases section as noted below, you can also use the PowerShell command tcpkg download [package name] -o [output location] +
+ +

Download from GitHub Releases

+ +
    +
  1. Navigate to the GitHub Releases page
  2. +
  3. Find the latest release (or the version you need)
  4. +
  5. Download the package file (.zip)
  6. +
  7. Transfer the files to your target system in an easy to remember location (Example: C:\Program Files\Beckhoff USA Community\Feeds\Local)
  8. +
+ +

Add Local Package Feed via GUI

+ +

If you haven’t already, add the Beckhoff USA Community package feed to TwinCAT Package Manager:

+ +
    +
  1. Open the TwinCAT Package Manager GUI
  2. +
  3. Click the Settings (Gear Icon) in the bottom left corner
  4. +
  5. Select Feeds
  6. +
+ +

For the feed settings use:

+
C:\Program Files\Beckhoff USA Community\Feeds\Local
+
+

For the feed name use:

+
Beckhoff USA Community Local
+
+

Deselect the Set credentials option, as we do not need login for the feed. Select Save.

+ +

Add Package Feed via Powershell

+ +
tcpkg source add -n "Beckhoff USA Community Local" -s "C:\Program Files\Beckhoff USA Community\Feeds\Local"
+
+ +

Install Workloads

+ +

After the feed is added (locally or remote), and the VerifySignatures is disabled, you can now install the Workloads and Packages on the feed like you would normal Beckhoff Automation packages.

+ +

Next Steps

+ + + +

Troubleshooting

+ +

Service Won’t Start

+ +
    +
  • Verify .NET 8 Runtime is installed
  • +
  • Check Windows Event Viewer for error messages
  • +
  • Ensure no other service is using ADS port 26129
  • +
+ +

Videos Not Being Created

+ +
    +
  • Confirm TwinCAT Vision is saving images to the configured path
  • +
  • Check service configuration file for correct paths
  • +
  • Verify sufficient disk space is available
  • +
+ +

PLC Function Block Errors

+ +
    +
  • Ensure the library reference is added correctly
  • +
  • Verify the service is running
  • +
  • Check ADS communication settings
  • +
+ +

Support

+ +

Need help? Here are some resources:

+ + + +
+ +
+ + +
+
+
+
+
+ + + + +
+ + + + + + + diff --git a/gh_pages/_site/docs/hmi-usage/index.html b/gh_pages/_site/docs/hmi-usage/index.html new file mode 100644 index 0000000..dc76377 --- /dev/null +++ b/gh_pages/_site/docs/hmi-usage/index.html @@ -0,0 +1,796 @@ + + + + + + + + HMI NuGet Package Usage | Event Video Playback + + + + + +HMI NuGet Package Usage | Event Video Playback + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + +
+ + + + +
+
+ +

HMI NuGet Package Usage

+ + + +

Integrate video playback controls into your TwinCAT HMI and WPF applications

+ + + + + + + + + + +
+

Overview

+ +

The Event Video Playback HMI NuGet package provides ready-to-use WPF controls for displaying and controlling video playback in your HMI applications. This guide covers installation, configuration, and usage.

+ +

Installation

+ +

Prerequisites

+ +
    +
  • Visual Studio 2019 or later
  • +
  • TwinCAT HMI Framework (for HMI projects) or standalone WPF application
  • +
  • .NET 8 Framework
  • +
  • NuGet Package Manager
  • +
+ +

Install via NuGet

+ +

Option 1: Package Manager Console

+ +
Install-Package EventVideoPlayback.HMI
+
+ +

Option 2: NuGet Package Manager UI

+ +
    +
  1. Right-click on your project in Solution Explorer
  2. +
  3. Select Manage NuGet Packages
  4. +
  5. Click on Browse tab
  6. +
  7. Search for “EventVideoPlayback.HMI”
  8. +
  9. Click Install
  10. +
+ +

Option 3: Beckhoff USA Community Package Feed

+ +

Add the Beckhoff USA Community package feed to your NuGet sources:

+ +
    +
  1. Tools > Options > NuGet Package Manager > Package Sources
  2. +
  3. Click the + button
  4. +
  5. Name: Beckhoff USA Community
  6. +
  7. Source: https://packages.beckhoff-usa-community.com/nuget/v3/index.json
  8. +
  9. Click OK
  10. +
+ +

Then search for and install the package.

+ +

Video Player Control

+ +

Basic Usage

+ +

Add the video player control to your XAML:

+ +
<Window x:Class="YourNamespace.MainWindow"
+        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+        xmlns:evp="clr-namespace:EventVideoPlayback.HMI.Controls;assembly=EventVideoPlayback.HMI"
+        Title="Event Video Playback" Height="600" Width="800">
+
+    <Grid>
+        <evp:EventVideoPlayer x:Name="videoPlayer"
+                              VideoSource="{Binding CurrentVideoPath}"
+                              AutoPlay="True"
+                              ShowControls="True"
+                              Volume="0.5" />
+    </Grid>
+</Window>
+
+ +

Control Properties

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeDefaultDescription
VideoSourcestringnullPath to the video file to play
AutoPlayboolfalseAutomatically start playback when source is set
ShowControlsbooltrueDisplay playback controls
Volumedouble0.5Volume level (0.0 to 1.0)
IsMutedboolfalseMute audio
LoopboolfalseLoop video playback
StretchStretchUniformHow video is stretched to fill control
+ +

Control Methods

+ +
// Play the video
+videoPlayer.Play();
+
+// Pause the video
+videoPlayer.Pause();
+
+// Stop the video
+videoPlayer.Stop();
+
+// Seek to specific position (in seconds)
+videoPlayer.Seek(10.5);
+
+// Load a new video
+videoPlayer.LoadVideo("C:\\Videos\\MachineEvent_001.mp4");
+
+// Take a snapshot
+videoPlayer.SaveSnapshot("C:\\Snapshots\\snapshot.png");
+
+ +

Events

+ +
// Video loaded and ready to play
+videoPlayer.VideoLoaded += (sender, e) =>
+{
+    Debug.WriteLine($"Video loaded: {e.VideoPath}");
+};
+
+// Playback started
+videoPlayer.PlaybackStarted += (sender, e) =>
+{
+    Debug.WriteLine("Playback started");
+};
+
+// Playback paused
+videoPlayer.PlaybackPaused += (sender, e) =>
+{
+    Debug.WriteLine("Playback paused");
+};
+
+// Playback completed
+videoPlayer.PlaybackCompleted += (sender, e) =>
+{
+    Debug.WriteLine("Playback completed");
+};
+
+// Error occurred
+videoPlayer.ErrorOccurred += (sender, e) =>
+{
+    MessageBox.Show($"Error: {e.ErrorMessage}", "Video Error");
+};
+
+ +

Complete Example Application

+ +

XAML (MainWindow.xaml)

+ +
<Window x:Class="VideoPlaybackDemo.MainWindow"
+        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+        xmlns:evp="clr-namespace:EventVideoPlayback.HMI.Controls;assembly=EventVideoPlayback.HMI"
+        Title="Event Video Playback Demo"
+        Height="700" Width="1000"
+        Loaded="Window_Loaded">
+
+    <Grid Background="#1a1a1a">
+        <Grid.RowDefinitions>
+            <RowDefinition Height="Auto"/>
+            <RowDefinition Height="*"/>
+            <RowDefinition Height="Auto"/>
+        </Grid.RowDefinitions>
+
+        <!-- Header -->
+        <Border Grid.Row="0" Background="#D32F2F" Padding="15">
+            <TextBlock Text="Event Video Playback Viewer"
+                       FontSize="24"
+                       FontWeight="Bold"
+                       Foreground="White"/>
+        </Border>
+
+        <!-- Video Player -->
+        <evp:EventVideoPlayer Grid.Row="1"
+                              x:Name="videoPlayer"
+                              Margin="10"
+                              ShowControls="True"
+                              Volume="0.7"/>
+
+        <!-- Video List and Controls -->
+        <Grid Grid.Row="2" Margin="10">
+            <Grid.ColumnDefinitions>
+                <ColumnDefinition Width="*"/>
+                <ColumnDefinition Width="Auto"/>
+            </Grid.ColumnDefinitions>
+
+            <!-- Video List -->
+            <ListBox Grid.Column="0"
+                     x:Name="videoListBox"
+                     SelectionChanged="VideoListBox_SelectionChanged"
+                     Background="#2a2a2a"
+                     Foreground="White"
+                     Padding="5"
+                     Height="150">
+                <ListBox.ItemTemplate>
+                    <DataTemplate>
+                        <StackPanel Orientation="Horizontal">
+                            <TextBlock Text="📹" Margin="0,0,10,0"/>
+                            <TextBlock Text="{Binding Name}"/>
+                        </StackPanel>
+                    </DataTemplate>
+                </ListBox.ItemTemplate>
+            </ListBox>
+
+            <!-- Control Buttons -->
+            <StackPanel Grid.Column="1" Margin="10,0,0,0" VerticalAlignment="Center">
+                <Button Content="Refresh List"
+                        Click="RefreshList_Click"
+                        Padding="15,5"
+                        Margin="0,0,0,5"
+                        Background="#D32F2F"
+                        Foreground="White"
+                        BorderThickness="0"
+                        Cursor="Hand"/>
+                <Button Content="Open Folder"
+                        Click="OpenFolder_Click"
+                        Padding="15,5"
+                        Margin="0,0,0,5"
+                        Background="#424242"
+                        Foreground="White"
+                        BorderThickness="0"
+                        Cursor="Hand"/>
+                <Button Content="Take Snapshot"
+                        Click="TakeSnapshot_Click"
+                        Padding="15,5"
+                        Background="#424242"
+                        Foreground="White"
+                        BorderThickness="0"
+                        Cursor="Hand"/>
+            </StackPanel>
+        </Grid>
+    </Grid>
+</Window>
+
+ +

Code-Behind (MainWindow.xaml.cs)

+ +
using System;
+using System.IO;
+using System.Linq;
+using System.Windows;
+using System.Diagnostics;
+using EventVideoPlayback.HMI.Controls;
+
+namespace VideoPlaybackDemo
+{
+    public partial class MainWindow : Window
+    {
+        private const string VIDEO_FOLDER = @"C:\TwinCAT\EventVideoPlayback\Videos";
+
+        public MainWindow()
+        {
+            InitializeComponent();
+        }
+
+        private void Window_Loaded(object sender, RoutedEventArgs e)
+        {
+            // Subscribe to video player events
+            videoPlayer.VideoLoaded += VideoPlayer_VideoLoaded;
+            videoPlayer.ErrorOccurred += VideoPlayer_ErrorOccurred;
+            videoPlayer.PlaybackCompleted += VideoPlayer_PlaybackCompleted;
+
+            // Load initial video list
+            RefreshVideoList();
+        }
+
+        private void RefreshVideoList()
+        {
+            try
+            {
+                if (!Directory.Exists(VIDEO_FOLDER))
+                {
+                    MessageBox.Show($"Video folder not found: {VIDEO_FOLDER}",
+                                    "Error",
+                                    MessageBoxButton.OK,
+                                    MessageBoxImage.Error);
+                    return;
+                }
+
+                var videoFiles = Directory.GetFiles(VIDEO_FOLDER, "*.mp4")
+                                          .Select(f => new FileInfo(f))
+                                          .OrderByDescending(f => f.CreationTime)
+                                          .ToList();
+
+                videoListBox.ItemsSource = videoFiles;
+
+                // Auto-select first video
+                if (videoFiles.Any())
+                {
+                    videoListBox.SelectedIndex = 0;
+                }
+            }
+            catch (Exception ex)
+            {
+                MessageBox.Show($"Error loading video list: {ex.Message}",
+                                "Error",
+                                MessageBoxButton.OK,
+                                MessageBoxImage.Error);
+            }
+        }
+
+        private void VideoListBox_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
+        {
+            if (videoListBox.SelectedItem is FileInfo fileInfo)
+            {
+                videoPlayer.LoadVideo(fileInfo.FullName);
+            }
+        }
+
+        private void RefreshList_Click(object sender, RoutedEventArgs e)
+        {
+            RefreshVideoList();
+        }
+
+        private void OpenFolder_Click(object sender, RoutedEventArgs e)
+        {
+            try
+            {
+                if (Directory.Exists(VIDEO_FOLDER))
+                {
+                    Process.Start("explorer.exe", VIDEO_FOLDER);
+                }
+                else
+                {
+                    MessageBox.Show($"Folder not found: {VIDEO_FOLDER}",
+                                    "Error",
+                                    MessageBoxButton.OK,
+                                    MessageBoxImage.Warning);
+                }
+            }
+            catch (Exception ex)
+            {
+                MessageBox.Show($"Error opening folder: {ex.Message}",
+                                "Error",
+                                MessageBoxButton.OK,
+                                MessageBoxImage.Error);
+            }
+        }
+
+        private void TakeSnapshot_Click(object sender, RoutedEventArgs e)
+        {
+            try
+            {
+                string snapshotPath = Path.Combine(
+                    VIDEO_FOLDER,
+                    $"Snapshot_{DateTime.Now:yyyyMMdd_HHmmss}.png"
+                );
+
+                videoPlayer.SaveSnapshot(snapshotPath);
+
+                MessageBox.Show($"Snapshot saved to:\n{snapshotPath}",
+                                "Snapshot Saved",
+                                MessageBoxButton.OK,
+                                MessageBoxImage.Information);
+            }
+            catch (Exception ex)
+            {
+                MessageBox.Show($"Error saving snapshot: {ex.Message}",
+                                "Error",
+                                MessageBoxButton.OK,
+                                MessageBoxImage.Error);
+            }
+        }
+
+        private void VideoPlayer_VideoLoaded(object sender, VideoLoadedEventArgs e)
+        {
+            // Optional: Update UI when video loads
+            Title = $"Event Video Playback - {Path.GetFileName(e.VideoPath)}";
+        }
+
+        private void VideoPlayer_ErrorOccurred(object sender, VideoErrorEventArgs e)
+        {
+            MessageBox.Show($"Video playback error:\n{e.ErrorMessage}",
+                            "Playback Error",
+                            MessageBoxButton.OK,
+                            MessageBoxImage.Error);
+        }
+
+        private void VideoPlayer_PlaybackCompleted(object sender, EventArgs e)
+        {
+            // Optional: Auto-play next video
+            if (videoListBox.SelectedIndex < videoListBox.Items.Count - 1)
+            {
+                videoListBox.SelectedIndex++;
+            }
+        }
+    }
+}
+
+ +

Integration with TwinCAT HMI

+ +

For TwinCAT HMI projects, the control can be integrated with symbol bindings:

+ +
<evp:EventVideoPlayer VideoSource="{Binding PLC.VideoPath, Mode=OneWay}"
+                      AutoPlay="{Binding PLC.AutoPlayEnabled, Mode=OneWay}"
+                      Volume="{Binding HMI.VolumeLevel, Mode=TwoWay}"/>
+
+ +

Styling and Customization

+ +

Custom Control Template

+ +

You can customize the appearance of the video player:

+ +
<evp:EventVideoPlayer x:Name="videoPlayer">
+    <evp:EventVideoPlayer.Style>
+        <Style TargetType="evp:EventVideoPlayer">
+            <Setter Property="Background" Value="#1a1a1a"/>
+            <Setter Property="Foreground" Value="White"/>
+            <Setter Property="BorderBrush" Value="#D32F2F"/>
+            <Setter Property="BorderThickness" Value="2"/>
+        </Style>
+    </evp:EventVideoPlayer.Style>
+</evp:EventVideoPlayer>
+
+ +

Performance Tips

+ +
    +
  1. Preload Videos: Load videos in background threads to avoid UI freezing
  2. +
  3. Hardware Acceleration: Ensure GPU acceleration is enabled
  4. +
  5. File Formats: Use H.264 (avc1) codec for best compatibility
  6. +
  7. Resolution: Match video resolution to display size
  8. +
  9. Memory Management: Dispose of video player when not in use
  10. +
+ +

Troubleshooting

+ +

Video Won’t Play

+ +
    +
  • Verify the video file exists and is accessible
  • +
  • Check that the codec is supported (H.264 recommended)
  • +
  • Ensure .NET 8 runtime is installed
  • +
  • Try playing the video in Windows Media Player to verify it’s valid
  • +
+ +

Control Not Visible

+ +
    +
  • Check that the NuGet package is correctly installed
  • +
  • Verify XAML namespace declaration
  • +
  • Ensure the control has proper Width/Height or is in a sized container
  • +
+ +

Performance Issues

+ +
    +
  • Reduce video resolution
  • +
  • Use hardware acceleration
  • +
  • Close other resource-intensive applications
  • +
  • Check CPU and GPU usage
  • +
+ +

Best Practices

+ +
    +
  1. Error Handling: Always subscribe to ErrorOccurred event
  2. +
  3. Resource Cleanup: Dispose of video player when closing window
  4. +
  5. File Validation: Verify video files exist before loading
  6. +
  7. User Feedback: Show loading indicators for long operations
  8. +
  9. Testing: Test with various video formats and resolutions
  10. +
+ +

Next Steps

+ + + +
+ +
+ + +
+
+
+
+
+ + + + +
+ + + + + + + diff --git a/gh_pages/_site/docs/plc-usage/index.html b/gh_pages/_site/docs/plc-usage/index.html new file mode 100644 index 0000000..90ed7ee --- /dev/null +++ b/gh_pages/_site/docs/plc-usage/index.html @@ -0,0 +1,718 @@ + + + + + + + + PLC Library Usage | Event Video Playback + + + + + +PLC Library Usage | Event Video Playback + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + +
+ + + + +
+
+ +

PLC Library Usage

+ + + +

Complete guide to using Event Video Playback function blocks in your TwinCAT PLC projects

+ + + + + + + + + + +
+

Overview

+ +

The Event Video Playback PLC library provides easy-to-use function blocks for integrating event-driven video recording into your TwinCAT applications. This guide covers the complete API and usage patterns.

+ +

Library Reference

+ +

Adding the Library

+ +

In your TwinCAT PLC project:

+ +
    +
  1. Right-click on References
  2. +
  3. Select Add Library
  4. +
  5. Search for “EventVideoPlayback”
  6. +
  7. Select the library and click OK
  8. +
+ +

The library will now be available for use in your PLC programs.

+ +

Core Function Blocks

+ +

FB_EventVideoRecorder

+ +

The main function block for recording event-driven videos from TwinCAT Vision images.

+ +

Declaration

+ +
VAR
+    fbVideoRecorder : FB_EventVideoRecorder;
+END_VAR
+
+ +

Input Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParameterTypeDescription
sVideoNameSTRINGUnique name for the video file
bExecuteBOOLRising edge triggers video creation
tPreEventTimeTIMEDuration of pre-event video to include (default: 10s)
tPostEventTimeTIMEDuration of post-event video to include (default: 5s)
sImagePathSTRINGPath to TwinCAT Vision image folder
bLogToEventLoggerBOOLEnable automatic Event Logger integration
+ +

Output Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParameterTypeDescription
bDoneBOOLTRUE when video creation is complete
bBusyBOOLTRUE while video is being created
bErrorBOOLTRUE if an error occurred
nErrorIDUDINTError code (0 = no error)
sVideoPathSTRINGFull path to the created video file
+ +

Usage Example

+ +
PROGRAM MAIN
+VAR
+    fbVideoRecorder : FB_EventVideoRecorder;
+    bMachineError   : BOOL;
+    bEventTriggered : BOOL;
+    sEventName      : STRING(255);
+END_VAR
+
+// Detect machine error event
+IF bMachineError AND NOT bEventTriggered THEN
+    bEventTriggered := TRUE;
+    sEventName := CONCAT('MachineError_', TO_STRING(NOW()));
+END_IF
+
+// Record video on event
+fbVideoRecorder(
+    sVideoName := sEventName,
+    bExecute := bEventTriggered,
+    tPreEventTime := T#15S,  // 15 seconds before event
+    tPostEventTime := T#10S,  // 10 seconds after event
+    sImagePath := 'C:\TwinCAT\Vision\Images',
+    bLogToEventLogger := TRUE
+);
+
+// Reset trigger when done
+IF fbVideoRecorder.bDone OR fbVideoRecorder.bError THEN
+    bEventTriggered := FALSE;
+END_IF
+
+// Handle errors
+IF fbVideoRecorder.bError THEN
+    // Log error code: fbVideoRecorder.nErrorID
+    // Take corrective action
+END_IF
+
+ +

Advanced Usage Patterns

+ +

Multiple Event Types

+ +

Handle different types of events with separate video recordings:

+ +
PROGRAM MAIN
+VAR
+    fbVideoQuality    : FB_EventVideoRecorder;
+    fbVideoMaintenance : FB_EventVideoRecorder;
+    fbVideoSafety     : FB_EventVideoRecorder;
+
+    bQualityIssue     : BOOL;
+    bMaintenanceNeeded : BOOL;
+    bSafetyEvent      : BOOL;
+END_VAR
+
+// Quality issue recording
+fbVideoQuality(
+    sVideoName := 'QualityIssue_' + TO_STRING(NOW()),
+    bExecute := bQualityIssue,
+    tPreEventTime := T#20S,
+    bLogToEventLogger := TRUE
+);
+
+// Maintenance event recording
+fbVideoMaintenance(
+    sVideoName := 'Maintenance_' + TO_STRING(NOW()),
+    bExecute := bMaintenanceNeeded,
+    tPreEventTime := T#30S,
+    bLogToEventLogger := TRUE
+);
+
+// Safety event recording
+fbVideoSafety(
+    sVideoName := 'Safety_' + TO_STRING(NOW()),
+    bExecute := bSafetyEvent,
+    tPreEventTime := T#60S,
+    tPostEventTime := T#30S,
+    bLogToEventLogger := TRUE
+);
+
+ +

Conditional Recording

+ +

Record videos only under specific conditions:

+ +
VAR
+    fbVideoRecorder : FB_EventVideoRecorder;
+    bEventOccurred  : BOOL;
+    bRecordEnabled  : BOOL := TRUE;
+    nEventSeverity  : UINT;
+    nMinSeverity    : UINT := 5;  // Only record severity >= 5
+END_VAR
+
+// Only record if enabled and severity threshold met
+IF bEventOccurred AND bRecordEnabled AND (nEventSeverity >= nMinSeverity) THEN
+    fbVideoRecorder(
+        sVideoName := CONCAT('Event_Severity_', TO_STRING(nEventSeverity)),
+        bExecute := TRUE,
+        bLogToEventLogger := TRUE
+    );
+END_IF
+
+ +

Sequence Recording

+ +

Record a sequence of related events:

+ +
TYPE E_RecordingState :
+(
+    IDLE,
+    RECORDING,
+    WAITING_FOR_NEXT,
+    COMPLETE
+);
+END_TYPE
+
+VAR
+    fbVideoRecorder   : FB_EventVideoRecorder;
+    eState            : E_RecordingState := IDLE;
+    nSequenceCount    : UINT := 0;
+    nMaxSequences     : UINT := 5;
+    bStartSequence    : BOOL;
+END_VAR
+
+CASE eState OF
+    IDLE:
+        IF bStartSequence THEN
+            nSequenceCount := 0;
+            eState := RECORDING;
+        END_IF
+
+    RECORDING:
+        fbVideoRecorder(
+            sVideoName := CONCAT('Sequence_', TO_STRING(nSequenceCount)),
+            bExecute := TRUE
+        );
+
+        IF fbVideoRecorder.bDone THEN
+            nSequenceCount := nSequenceCount + 1;
+
+            IF nSequenceCount >= nMaxSequences THEN
+                eState := COMPLETE;
+            ELSE
+                eState := WAITING_FOR_NEXT;
+            END_IF
+        END_IF
+
+    WAITING_FOR_NEXT:
+        // Wait for condition to trigger next recording
+        IF bTriggerNextRecording THEN
+            eState := RECORDING;
+        END_IF
+
+    COMPLETE:
+        // All sequences recorded
+        eState := IDLE;
+END_CASE
+
+ +

Error Handling

+ +

Error Codes

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Error IDDescriptionResolution
0No errorN/A
1001Service not availableCheck if EventVideoPlayback service is running
1002Invalid image pathVerify sImagePath is correct
1003Insufficient imagesEnsure Vision system is capturing images
1004Video creation failedCheck service logs for details
1005Disk space insufficientFree up disk space
1006Invalid parametersCheck input parameter values
+ +

Error Handling Example

+ +
VAR
+    fbVideoRecorder : FB_EventVideoRecorder;
+    sErrorMessage   : STRING(255);
+END_VAR
+
+IF fbVideoRecorder.bError THEN
+    CASE fbVideoRecorder.nErrorID OF
+        1001:
+            sErrorMessage := 'EventVideoPlayback service is not running';
+            // Attempt to restart service or notify maintenance
+
+        1002:
+            sErrorMessage := 'Invalid image path configured';
+            // Log configuration error
+
+        1003:
+            sErrorMessage := 'Not enough images available for video';
+            // Check Vision system status
+
+        1004:
+            sErrorMessage := 'Video creation failed';
+            // Check service logs and disk space
+
+        1005:
+            sErrorMessage := 'Insufficient disk space';
+            // Trigger cleanup or notification
+
+        ELSE:
+            sErrorMessage := CONCAT('Unknown error: ', TO_STRING(fbVideoRecorder.nErrorID));
+    END_CASE
+
+    // Log error to Event Logger or HMI
+END_IF
+
+ +

Best Practices

+ +

1. Unique Video Names

+ +

Always use unique video names to avoid conflicts:

+ +
// Good: Include timestamp
+sVideoName := CONCAT('Event_', TO_STRING(NOW()));
+
+// Better: Include machine ID and event type
+sVideoName := CONCAT('Machine01_QualityIssue_', TO_STRING(NOW()));
+
+ +

2. Appropriate Time Windows

+ +

Choose pre/post event times based on your needs:

+ +
    +
  • Fast events (< 1 second): Use 5-10 seconds pre-event
  • +
  • Slow events (> 10 seconds): Use 30-60 seconds pre-event
  • +
  • Post-event: Usually 5-10 seconds is sufficient
  • +
+ +

3. Resource Management

+ +

Don’t create videos too frequently:

+ +
VAR
+    fbVideoRecorder    : FB_EventVideoRecorder;
+    tLastRecording     : TIME;
+    tMinInterval       : TIME := T#30S;  // Minimum 30s between recordings
+END_VAR
+
+IF (TIME() - tLastRecording) > tMinInterval THEN
+    // Allow recording
+    tLastRecording := TIME();
+END_IF
+
+ +

4. Event Logger Integration

+ +

Enable Event Logger integration for automatic correlation:

+ +
fbVideoRecorder(
+    sVideoName := sEventName,
+    bExecute := bEvent,
+    bLogToEventLogger := TRUE  // Automatically creates Event Logger entry
+);
+
+ +

Performance Considerations

+ +
    +
  • Image Buffer: The service maintains a rolling buffer of images
  • +
  • CPU Usage: Video encoding is performed by the service, not PLC
  • +
  • Network Impact: Minimal - only ADS communication for commands
  • +
  • Disk I/O: Configure video output path on fast storage
  • +
+ +

Next Steps

+ + + +
+ +
+ + +
+
+
+
+
+ + + + +
+ + + + + + + diff --git a/gh_pages/_site/docs/service-config/index.html b/gh_pages/_site/docs/service-config/index.html new file mode 100644 index 0000000..0701ce4 --- /dev/null +++ b/gh_pages/_site/docs/service-config/index.html @@ -0,0 +1,774 @@ + + + + + + + + Service Configuration | Event Video Playback + + + + + +Service Configuration | Event Video Playback + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + +
+ + + + +
+
+ +

Service Configuration

+ + + +

Configure the EventVideoPlayback Windows service for optimal performance

+ + + + + + + + + + +
+

Overview

+ +

The EventVideoPlayback Service is a Windows background service that handles video creation and automatic file management. This guide covers all configuration options and troubleshooting steps.

+ +

Configuration File Location

+ +

The service configuration file is located at:

+ +
C:\Program Files\Beckhoff USA Community\EventVideoPlayback\Service\EventVideoPlaybackService.config.json
+
+ +

Open this file with Notepad, Visual Studio, or any text editor.

+ +

Configuration Parameters

+ +

Default Configuration

+ +
{
+  "CodecFourCC": "avc1",
+  "VideoDeleteTime": 1,
+  "AdsPort": 26129,
+  "MaxFolderSize": 250
+}
+
+ +

CodecFourCC

+ +

Type: String +Default: "avc1" +Description: The video codec used to create MP4 videos from image sequences.

+ +

The avc1 codec (H.264) is recommended as it provides:

+
    +
  • Excellent compression
  • +
  • Wide compatibility with web browsers
  • +
  • Support for TwinCAT HMI playback
  • +
  • Good balance between quality and file size
  • +
+ +

Supported Codecs

+ +

The service supports multiple codecs, but not all are web-compatible. For TwinCAT HMI compatibility, stick with these recommended options:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
CodecFourCCDescriptionWeb CompatibleRecommended
H.264avc1Most common, best compatibilityYes
H.264avc3Alternative H.264 variantYes
H.265/HEVChev1Better compression, newerMaybe
H.265/HEVChvc1Alternative HEVC variantMaybe
MPEG-4mp4vOlder standardNo
VP9vp09Google’s codecNo
AV1av01Newest, best compressionNo
+ +

Changing the Codec

+ +

To change the codec, edit the configuration file:

+ +
{
+  "CodecFourCC": "hev1",  // Changed to H.265
+  "VideoDeleteTime": 1,
+  "AdsPort": 26129,
+  "MaxFolderSize": 250
+}
+
+ +

⚠ Important: After changing any configuration, you must restart the service for changes to take effect.

+ +

VideoDeleteTime

+ +

Type: Decimal (floating-point) +Default: 1 +Units: Days +Description: How long video files are kept before automatic deletion.

+ +

The service automatically cleans up old videos based on this setting. This helps manage disk space and keep only relevant videos.

+ +

Examples

+ +
// Keep videos for 1 day (default)
+"VideoDeleteTime": 1
+
+// Keep videos for 12 hours
+"VideoDeleteTime": 0.5
+
+// Keep videos for 1 week
+"VideoDeleteTime": 7
+
+// Keep videos for 30 days
+"VideoDeleteTime": 30
+
+// Keep videos for 2 hours
+"VideoDeleteTime": 0.083
+
+ +

Calculation Reference

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DurationValueCalculation
1 hour0.0421/24
6 hours0.256/24
12 hours0.512/24
1 day1.024/24
3 days3.0-
1 week7.0-
1 month30.0-
+ +

AdsPort

+ +

Type: Integer +Default: 26129 +Description: The ADS port number the service listens on.

+ +

⚠ WARNING: DO NOT CHANGE THIS VALUE

+ +

The PLC function blocks are configured to communicate with the service on port 26129. Changing this value will break PLC communication.

+ +

If you have a specific need to use a different port, you must:

+
    +
  1. Change this configuration value
  2. +
  3. Recompile the PLC library with the new port number
  4. +
  5. Update all PLC projects using the library
  6. +
+ +

MaxFolderSize

+ +

Type: Integer +Default: 250 +Units: Megabytes (MB) +Description: Maximum total size of the video folder.

+ +

When a new video is created, the service checks the total folder size. If it exceeds this limit, the oldest videos are automatically deleted to free space.

+ +

Examples

+ +
// Limit to 250 MB (default)
+"MaxFolderSize": 250
+
+// Limit to 1 GB
+"MaxFolderSize": 1024
+
+// Limit to 5 GB
+"MaxFolderSize": 5120
+
+// Limit to 500 MB
+"MaxFolderSize": 500
+
+ +

Size Planning

+ +

Consider these factors when setting folder size:

+ +
    +
  • Video duration: Longer pre/post event times = larger files
  • +
  • Image resolution: Higher resolution = larger files
  • +
  • Frame rate: More frames per second = larger files
  • +
  • Codec: Different codecs have different compression ratios
  • +
  • Event frequency: More frequent events = more videos
  • +
+ +

Example Calculation:

+
    +
  • Average video duration: 30 seconds
  • +
  • Average file size: 5 MB per video
  • +
  • MaxFolderSize: 250 MB
  • +
  • Approximate capacity: ~50 videos
  • +
+ +

Applying Configuration Changes

+ +

After modifying the configuration file:

+ +

Option 1: Restart the Service

+ +
    +
  1. Open Windows Services (services.msc)
  2. +
  3. Find EventVideoPlayback Service
  4. +
  5. Right-click and select Restart
  6. +
+ +

Option 2: Use Command Line

+ +
# Stop the service
+net stop "EventVideoPlayback Service"
+
+# Start the service
+net start "EventVideoPlayback Service"
+
+ +

Option 3: Reboot

+ +

A system reboot will also restart the service with the new configuration.

+ +

Advanced Configuration

+ +

Example: High-Quality, Long Retention

+ +

For critical systems where video quality and retention are important:

+ +
{
+  "CodecFourCC": "avc1",
+  "VideoDeleteTime": 30,      // Keep for 30 days
+  "AdsPort": 26129,
+  "MaxFolderSize": 10240      // 10 GB
+}
+
+ +

Example: Space-Constrained, Short Retention

+ +

For systems with limited disk space:

+ +
{
+  "CodecFourCC": "avc1",
+  "VideoDeleteTime": 0.5,     // Keep for 12 hours
+  "AdsPort": 26129,
+  "MaxFolderSize": 100        // 100 MB
+}
+
+ +

Example: Maximum Compression

+ +

For maximum file size reduction:

+ +
{
+  "CodecFourCC": "hev1",      // H.265 for better compression
+  "VideoDeleteTime": 7,       // Keep for 1 week
+  "AdsPort": 26129,
+  "MaxFolderSize": 500        // 500 MB
+}
+
+ +

Service Management

+ +

Checking Service Status

+ +

Windows Services GUI:

+
    +
  1. Press Win + R, type services.msc, press Enter
  2. +
  3. Find “EventVideoPlayback Service”
  4. +
  5. Check the Status column (should show “Running”)
  6. +
+ +

PowerShell:

+
Get-Service -Name "EventVideoPlayback*"
+
+ +

Command Prompt:

+
sc query "EventVideoPlayback Service"
+
+ +

Starting the Service

+ +
Start-Service -Name "EventVideoPlayback Service"
+
+ +

Stopping the Service

+ +
Stop-Service -Name "EventVideoPlayback Service"
+
+ +

Setting Startup Type

+ +

Automatic (recommended):

+
Set-Service -Name "EventVideoPlayback Service" -StartupType Automatic
+
+ +

Manual:

+
Set-Service -Name "EventVideoPlayback Service" -StartupType Manual
+
+ +

Troubleshooting

+ +

Service Won’t Start

+ +

Check Event Viewer:

+
    +
  1. Open Event Viewer (eventvwr.msc)
  2. +
  3. Navigate to Windows Logs > Application
  4. +
  5. Look for errors from source “EventVideoPlayback”
  6. +
+ +

Common Causes:

+
    +
  • Missing .NET 8 Runtime
  • +
  • Invalid configuration file (JSON syntax error)
  • +
  • Port 26129 already in use
  • +
  • Insufficient permissions
  • +
+ +

Solutions:

+
# Verify .NET 8 Runtime is installed
+dotnet --list-runtimes
+
+# Check if port is in use
+netstat -ano | findstr "26129"
+
+# Run as administrator
+net start "EventVideoPlayback Service"
+
+ +

Configuration Not Taking Effect

+ +
    +
  • Verify you saved the configuration file
  • +
  • Ensure JSON syntax is valid (use a JSON validator)
  • +
  • Restart the service after changes
  • +
  • Check file permissions (service must be able to read the file)
  • +
+ +

Videos Not Being Deleted

+ +
    +
  • Verify VideoDeleteTime is set appropriately
  • +
  • Check that the service has write permissions to the video folder
  • +
  • Ensure the system clock is correct
  • +
  • Review service logs for cleanup errors
  • +
+ +

Disk Space Issues

+ +

If you’re running out of disk space:

+ +
    +
  1. Reduce MaxFolderSize: +
    "MaxFolderSize": 100  // Reduce to 100 MB
    +
    +
  2. +
  3. Reduce VideoDeleteTime: +
    "VideoDeleteTime": 0.5  // Keep only 12 hours
    +
    +
  4. +
  5. Manually clean old videos: +
      +
    • Navigate to the video output folder
    • +
    • Delete old MP4 files
    • +
    • Service will manage space going forward
    • +
    +
  6. +
+ +

Performance Issues

+ +

If video creation is slow:

+ +
    +
  • Check CPU usage: Video encoding is CPU-intensive
  • +
  • Use faster storage: SSD is recommended for video output
  • +
  • Reduce image resolution: Lower resolution = faster encoding
  • +
  • Consider codec: H.264 (avc1) is generally fastest
  • +
+ +

Monitoring and Logging

+ +

Log File Location

+ +

Service logs are typically located at:

+
C:\Program Files\Beckhoff USA Community\EventVideoPlayback\Service\Logs\
+
+ +

Log Contents

+ +

Logs include:

+
    +
  • Service startup and shutdown events
  • +
  • Video creation requests and completions
  • +
  • File cleanup operations
  • +
  • Errors and warnings
  • +
  • ADS communication status
  • +
+ +

Viewing Logs

+ +

Use any text editor or PowerShell:

+ +
# View latest log file
+Get-Content "C:\Program Files\Beckhoff USA Community\EventVideoPlayback\Service\Logs\*.log" -Tail 50
+
+ +

Best Practices

+ +
    +
  1. Regular Monitoring: Check service status weekly
  2. +
  3. Disk Space: Ensure adequate free space (at least 2x MaxFolderSize)
  4. +
  5. Backup Configuration: Keep a copy of your configuration file
  6. +
  7. Test Changes: Test configuration changes in a development environment first
  8. +
  9. Document Settings: Document why you chose specific values
  10. +
+ +

Next Steps

+ + + +
+ +
+ + +
+
+
+
+
+ + + + +
+ + + + + + + diff --git a/gh_pages/_site/feed.xml b/gh_pages/_site/feed.xml new file mode 100644 index 0000000..24c87c9 --- /dev/null +++ b/gh_pages/_site/feed.xml @@ -0,0 +1 @@ +Jekyll2025-11-11T07:46:24-08:00http://localhost:4000/EventVideoPlayback/feed.xmlEvent Video PlaybackTransform TwinCAT Vision images into event-driven video recordings \ No newline at end of file diff --git a/gh_pages/_site/index.html b/gh_pages/_site/index.html new file mode 100644 index 0000000..b18ef95 --- /dev/null +++ b/gh_pages/_site/index.html @@ -0,0 +1,214 @@ + + + + + + + + Event Video Playback | Event Video Playback + + + + + +Event Video Playback | Transform TwinCAT Vision images into event-driven video recordings + + + + + + + + + + + + + + + + + + + +
+
+
+ Event Video Playback +

Event Video Playback

+

Transform TwinCAT Vision images into event-driven video recordings

+ +
+
+ +
+
+
+

Powerful Features for Industrial Automation

+

Everything you need to capture, log, and review event-driven video from TwinCAT Vision

+
+
+
+ 📹 +

Event-Driven Capture

+

Automatically capture and compile videos from TwinCAT Vision images when critical events occur. No manual intervention required.

+
+
+ 📊 +

Event Logging & HMI Playback

+

Seamlessly integrate with TwinCAT Event Logger for automatic video logging, then review and analyze recorded events directly from your HMI with intuitive playback controls.

+
+
+ 🔧 +

Easy PLC Integration

+

Simple-to-use PLC function blocks make integration into your existing TwinCAT projects quick and straightforward.

+
+
+
+
+ +
+
+
+
+

Why Event Video Playback?

+

In industrial automation, understanding what happened during critical events is crucial. Event Video Playback bridges the gap between TwinCAT Vision image capture and meaningful video documentation.

+

Real-World Example: When a machine down occurrence is triggered, the system automatically compiles recent images into a video, logs it with Event Logger, and makes it available for review on the HMI. Operators and engineers can quickly diagnose issues without manually searching through thousands of individual images.

+
+
+ Event Video Playback Overview +
+
+
+
+ +
+
+
+

System Requirements

+

Everything you need to get started with Event Video Playback

+
+
+
+ + TwinCAT 3.1 Build 4026 or higher +
+
+ + TwinCAT Vision Package
TwinCAT HMI Package
+
+
+ + Windows 10 or 11 +
+
+ +
+
+ +
+
+
+

Ready to Get Started?

+
+
+
+ 📦 +

Install With TwinCAT Package Manager

+

Quick installation using TwinCAT Package Manager for seamless integration with your TwinCAT environment.

+ Getting Started → +
+
+ 📖 +

PLC Developers

+

Learn how to integrate Event Video Playback function blocks into your TwinCAT PLC projects.

+ PLC Library Guide → +
+
+ 🖥️ +

HMI Developers

+

Add video playback controls to your HMI using the NuGet package for WPF applications.

+ HMI Package Guide → +
+
+ ⚙️ +

System Service Configuration

+

Configure the Windows service, set up video parameters, and troubleshoot installations.

+ Service Config → +
+
+
+
+ + +
+ + + + + + + diff --git a/gh_pages/_site/robots.txt b/gh_pages/_site/robots.txt new file mode 100644 index 0000000..ee6fcf3 --- /dev/null +++ b/gh_pages/_site/robots.txt @@ -0,0 +1 @@ +Sitemap: http://localhost:4000/EventVideoPlayback/sitemap.xml diff --git a/gh_pages/_site/sitemap.xml b/gh_pages/_site/sitemap.xml new file mode 100644 index 0000000..4622c74 --- /dev/null +++ b/gh_pages/_site/sitemap.xml @@ -0,0 +1,31 @@ + + + +http://localhost:4000/EventVideoPlayback/docs/getting-started/ +2025-11-11T07:46:24-08:00 + + +http://localhost:4000/EventVideoPlayback/docs/hmi-usage/ +2025-11-11T07:46:24-08:00 + + +http://localhost:4000/EventVideoPlayback/docs/plc-usage/ +2025-11-11T07:46:24-08:00 + + +http://localhost:4000/EventVideoPlayback/docs/service-config/ +2025-11-11T07:46:24-08:00 + + +http://localhost:4000/EventVideoPlayback/ + + +http://localhost:4000/EventVideoPlayback/DEPLOYMENT.html + + +http://localhost:4000/EventVideoPlayback/Event%20Video%20Playback%20Configuration.html + + +http://localhost:4000/EventVideoPlayback/assets/pdf/ + + diff --git a/gh_pages/assets/css/style.scss b/gh_pages/assets/css/style.scss new file mode 100644 index 0000000..d25d4ad --- /dev/null +++ b/gh_pages/assets/css/style.scss @@ -0,0 +1,8 @@ +--- +--- + +@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;700&display=swap'); + +@import "variables"; +@import "layout"; +@import "components"; diff --git a/gh_pages/assets/images/Camera_Hero_NoBackground.png b/gh_pages/assets/images/Camera_Hero_NoBackground.png new file mode 100644 index 0000000..c8d1146 Binary files /dev/null and b/gh_pages/assets/images/Camera_Hero_NoBackground.png differ diff --git a/gh_pages/assets/js/main.js b/gh_pages/assets/js/main.js new file mode 100644 index 0000000..8b0ae96 --- /dev/null +++ b/gh_pages/assets/js/main.js @@ -0,0 +1,107 @@ +// Mobile Menu Toggle +document.addEventListener('DOMContentLoaded', function() { + const mobileMenuToggle = document.querySelector('.mobile-menu-toggle'); + const siteNav = document.querySelector('.site-nav'); + + if (mobileMenuToggle) { + mobileMenuToggle.addEventListener('click', function() { + siteNav.classList.toggle('active'); + this.innerHTML = siteNav.classList.contains('active') ? '✕' : '☰'; + }); + + // Close menu when clicking a link + const navLinks = document.querySelectorAll('.site-nav a'); + navLinks.forEach(link => { + link.addEventListener('click', function() { + siteNav.classList.remove('active'); + mobileMenuToggle.innerHTML = '☰'; + }); + }); + + // Close menu when clicking outside + document.addEventListener('click', function(event) { + if (!siteNav.contains(event.target) && !mobileMenuToggle.contains(event.target)) { + siteNav.classList.remove('active'); + mobileMenuToggle.innerHTML = '☰'; + } + }); + } + + // Smooth scroll for anchor links + document.querySelectorAll('a[href^="#"]').forEach(anchor => { + anchor.addEventListener('click', function (e) { + const href = this.getAttribute('href'); + if (href !== '#') { + e.preventDefault(); + const target = document.querySelector(href); + if (target) { + const offsetTop = target.offsetTop - 70; // Account for fixed header + window.scrollTo({ + top: offsetTop, + behavior: 'smooth' + }); + } + } + }); + }); + + // Header shadow on scroll + const header = document.querySelector('.site-header'); + let lastScrollTop = 0; + + window.addEventListener('scroll', function() { + const scrollTop = window.pageYOffset || document.documentElement.scrollTop; + + if (scrollTop > 50) { + header.style.boxShadow = '0 4px 12px rgba(0, 0, 0, 0.3)'; + } else { + header.style.boxShadow = '0 2px 8px rgba(0, 0, 0, 0.15)'; + } + + lastScrollTop = scrollTop; + }); + + // Fade in elements on scroll + const observerOptions = { + threshold: 0.1, + rootMargin: '0px 0px -50px 0px' + }; + + const observer = new IntersectionObserver(function(entries) { + entries.forEach(entry => { + if (entry.isIntersecting) { + entry.target.style.opacity = '1'; + entry.target.style.transform = 'translateY(0)'; + } + }); + }, observerOptions); + + // Observe feature cards and other elements + const animatedElements = document.querySelectorAll('.feature-card, .overview, .requirement-item'); + animatedElements.forEach(el => { + el.style.opacity = '0'; + el.style.transform = 'translateY(30px)'; + el.style.transition = 'opacity 0.6s ease, transform 0.6s ease'; + observer.observe(el); + }); + + // Add loading animation complete + document.body.classList.add('loaded'); +}); + +// Copy code button for code blocks +document.querySelectorAll('pre code').forEach((block) => { + const button = document.createElement('button'); + button.className = 'copy-code-btn'; + button.textContent = 'Copy'; + button.addEventListener('click', () => { + navigator.clipboard.writeText(block.textContent).then(() => { + button.textContent = 'Copied!'; + setTimeout(() => { + button.textContent = 'Copy'; + }, 2000); + }); + }); + block.parentElement.style.position = 'relative'; + block.parentElement.appendChild(button); +}); diff --git a/gh_pages/assets/pdf-template/template.tex b/gh_pages/assets/pdf-template/template.tex new file mode 100644 index 0000000..21525bd --- /dev/null +++ b/gh_pages/assets/pdf-template/template.tex @@ -0,0 +1,163 @@ +% Event Video Playback Documentation Template +\documentclass[$if(fontsize)$$fontsize$,$endif$$if(lang)$$babel-lang$,$endif$$if(papersize)$$papersize$paper,$endif$$for(classoption)$$classoption$$sep$,$endfor$]{$documentclass$} + +% Packages +\usepackage{lmodern} +\usepackage{amssymb,amsmath} +\usepackage{ifxetex,ifluatex} +\usepackage{fixltx2e} +\usepackage[T1]{fontenc} +\usepackage[utf8]{inputenc} +\usepackage{microtype} +\usepackage[$for(geometry)$$geometry$$sep$,$endfor$]{geometry} +\usepackage{hyperref} +\usepackage{graphicx} +\usepackage{grffile} +\usepackage{longtable,booktabs} +\usepackage{listings} +\usepackage{fancyhdr} +\usepackage{lastpage} +\usepackage{xcolor} + +% Define colors (matching website theme) +\definecolor{primaryred}{RGB}{211,47,47} +\definecolor{darkred}{RGB}{198,40,40} +\definecolor{darkgray}{RGB}{33,33,33} +\definecolor{lightgray}{RGB}{245,245,245} +\definecolor{codebg}{RGB}{248,248,248} + +% Hyperref setup +\hypersetup{ + breaklinks=true, + bookmarks=true, + pdfauthor={$author-meta$}, + pdftitle={$title-meta$}, + colorlinks=true, + linkcolor=$if(linkcolor)$$linkcolor$$else$primaryred$endif$, + citecolor=$if(citecolor)$$citecolor$$else$blue$endif$, + urlcolor=$if(urlcolor)$$urlcolor$$else$primaryred$endif$, + pdfborder={0 0 0} +} + +% Headers and Footers +\pagestyle{fancy} +\fancyhf{} +\fancyhead[L]{\small\textcolor{darkgray}{$title$}} +\fancyhead[R]{\small\textcolor{darkgray}{Beckhoff USA Community}} +\fancyfoot[C]{\small\textcolor{darkgray}{Page \thepage\ of \pageref{LastPage}}} +\renewcommand{\headrulewidth}{0.5pt} +\renewcommand{\footrulewidth}{0.5pt} +\renewcommand{\headrule}{\hbox to\headwidth{\color{primaryred}\leaders\hrule height \headrulewidth\hfill}} +\renewcommand{\footrule}{\hbox to\headwidth{\color{primaryred}\leaders\hrule height \footrulewidth\hfill}} + +% Title formatting +\usepackage{titling} +\pretitle{\begin{center}\LARGE\bfseries\color{primaryred}} +\posttitle{\par\end{center}\vskip 0.5em} +\preauthor{\begin{center}\large\color{darkgray}} +\postauthor{\end{center}} +\predate{\begin{center}\large\color{darkgray}} +\postdate{\par\end{center}} + +% Section formatting +\usepackage{titlesec} +\titleformat{\section} + {\Large\bfseries\color{primaryred}} + {\thesection}{1em}{} +\titleformat{\subsection} + {\large\bfseries\color{darkgray}} + {\thesubsection}{1em}{} +\titleformat{\subsubsection} + {\normalsize\bfseries\color{darkgray}} + {\thesubsubsection}{1em}{} + +% Code listings +\lstset{ + backgroundcolor=\color{codebg}, + basicstyle=\small\ttfamily, + breaklines=true, + captionpos=b, + commentstyle=\color{darkgray}, + frame=single, + frameround=tttt, + rulecolor=\color{primaryred}, + keywordstyle=\color{primaryred}, + numbers=left, + numberstyle=\tiny\color{darkgray}, + stringstyle=\color{darkred}, + tabsize=2, + xleftmargin=2em, + framexleftmargin=1.5em +} + +% Inline code +\usepackage{listings} +\lstdefinestyle{inlinecode}{ + basicstyle=\ttfamily\small, + backgroundcolor=\color{codebg}, + breaklines=false +} + +% Table styling +\usepackage{array} +\usepackage{colortbl} +\arrayrulecolor{primaryred} +\renewcommand{\arraystretch}{1.2} + +% Pandoc compatibility +$if(highlighting-macros)$ +$highlighting-macros$ +$endif$ + +% Document metadata +$if(title)$ +\title{$title$} +$endif$ +$if(author)$ +\author{$for(author)$$author$$sep$ \and $endfor$} +$endif$ +$if(date)$ +\date{$date$} +$endif$ + +% Begin document +\begin{document} + +% Title page +$if(title)$ +\maketitle +$endif$ + +% Abstract +$if(abstract)$ +\begin{abstract} +$abstract$ +\end{abstract} +$endif$ + +% Table of contents +$if(toc)$ +{ +\hypersetup{linkcolor=black} +\setcounter{tocdepth}{$toc-depth$} +\tableofcontents +} +\newpage +$endif$ + +% Body +$body$ + +% Back matter +\vfill +\begin{center} +\color{darkgray} +\rule{0.5\textwidth}{0.4pt}\\[0.5em] +\small +Generated from Event Video Playback Documentation\\ +\textcopyright\ Beckhoff USA Community\\ +Licensed under MIT License\\ +\url{https://github.com/Beckhoff-USA-Community/EventVideoPlayback} +\end{center} + +\end{document} diff --git a/gh_pages/assets/pdf/.gitkeep b/gh_pages/assets/pdf/.gitkeep new file mode 100644 index 0000000..54bd05a --- /dev/null +++ b/gh_pages/assets/pdf/.gitkeep @@ -0,0 +1,2 @@ +# This directory contains auto-generated PDF documentation +# PDFs are generated by GitHub Actions workflow diff --git a/gh_pages/assets/pdf/README.md b/gh_pages/assets/pdf/README.md new file mode 100644 index 0000000..e8b5510 --- /dev/null +++ b/gh_pages/assets/pdf/README.md @@ -0,0 +1,155 @@ +# Documentation PDF Generation + +This directory contains auto-generated PDF versions of the Event Video Playback documentation. + +## 📄 Available PDFs + +The following PDFs are automatically generated from the markdown documentation: + +- **getting-started.pdf** - Installation and setup guide +- **plc-usage.pdf** - PLC library documentation +- **service-config.pdf** - Service configuration guide +- **hmi-usage.pdf** - HMI NuGet package guide +- **complete-documentation.pdf** - All documentation in one PDF + +## 🔄 How PDF Generation Works + +PDFs are automatically generated using **GitHub Actions** whenever documentation changes are pushed. + +### Workflow Trigger + +The PDF generation workflow (`.github/workflows/generate-docs-pdf.yml`) runs when: +- Changes are pushed to `gh_pages/_docs/` directory +- Changes are pushed to the PDF template +- Workflow is manually triggered via GitHub Actions UI + +### Generation Process + +1. **Pandoc** converts markdown files to PDF +2. Custom **LaTeX template** applies Event Video Playback branding (red/black theme) +3. PDFs include: + - Professional formatting + - Table of contents + - Headers and footers + - Color-coded links + - Code syntax highlighting + - Page numbers +4. Generated PDFs are committed back to this directory +5. PDFs become available for download on the website + +## 🎨 PDF Styling + +PDFs use a custom LaTeX template (`assets/pdf-template/template.tex`) that: +- Matches the website's red/black color scheme +- Uses primary red (#D32F2F) for headings and links +- Includes Beckhoff USA Community branding +- Provides professional headers and footers +- Formats code blocks with syntax highlighting + +## 🚀 Manual Workflow Trigger + +To manually regenerate PDFs: + +1. Go to **GitHub Actions** tab +2. Select **"Generate Documentation PDFs"** workflow +3. Click **"Run workflow"** +4. Choose branch (main or v2.0.0) +5. Click **"Run workflow"** button + +PDFs will be generated and committed within 2-3 minutes. + +## 📥 Download Buttons + +Each documentation page includes two download buttons: + +1. **"Download as PDF"** - Downloads the current page as PDF +2. **"Download Complete Docs"** - Downloads all documentation combined + +Buttons are styled with: +- White background with red border (current page) +- Red background with white text (complete docs) +- Hover animations +- Download icons from Feather Icons + +## 🔧 Customizing PDF Output + +### Modify Template + +Edit `assets/pdf-template/template.tex` to customize: +- Colors and branding +- Page layout and margins +- Header/footer content +- Font sizes and styles +- Code block styling + +### Modify Workflow + +Edit `.github/workflows/generate-docs-pdf.yml` to: +- Change Pandoc options +- Add/remove PDFs +- Adjust metadata (title, author, date) +- Configure PDF settings + +### Example: Change Margins + +In the workflow, modify the `--variable geometry:margin=` option: + +```yaml +--variable geometry:margin=1.5in # Larger margins +--variable geometry:margin=0.75in # Smaller margins +``` + +### Example: Change Font Size + +```yaml +--variable fontsize=12pt # Larger text +--variable fontsize=10pt # Smaller text +``` + +## 🐛 Troubleshooting + +### PDFs Not Generating + +1. Check GitHub Actions workflow status +2. Review workflow logs for errors +3. Ensure markdown syntax is valid +4. Verify LaTeX template syntax + +### PDF Formatting Issues + +- **Tables not displaying correctly**: Simplify table structure or use smaller font +- **Code blocks overflowing**: Use `breaklines=true` in listings settings +- **Links not working**: Ensure URLs are properly formatted in markdown + +### Force Regeneration + +If PDFs appear outdated: + +1. Make a small change to any doc file (add a space) +2. Commit and push +3. Workflow will run automatically + +Or trigger manually via GitHub Actions UI. + +## 📦 Dependencies + +The workflow requires: +- **Pandoc** - Document converter +- **LaTeX** (texlive) - PDF rendering engine +- Includes: texlive-latex-base, texlive-fonts-recommended, texlive-fonts-extra, texlive-latex-extra + +These are automatically installed by the GitHub Actions runner. + +## 📝 Notes + +- PDFs are committed with `[skip ci]` message to avoid infinite workflow loops +- Generated PDFs are tracked in git for easy access +- File sizes: ~100-500KB per PDF (depending on content) +- Generation time: ~30-60 seconds per PDF + +## 🔗 Links + +- [GitHub Actions Workflows](../../.github/workflows/) +- [PDF Template](../pdf-template/template.tex) +- [Documentation Source](_docs/) +- [Live Website](https://beckhoff-usa-community.github.io/EventVideoPlayback/) diff --git a/gh_pages/index.md b/gh_pages/index.md new file mode 100644 index 0000000..ac16bc5 --- /dev/null +++ b/gh_pages/index.md @@ -0,0 +1,118 @@ +--- +layout: home +title: Event Video Playback +description: Transform TwinCAT Vision images into event-driven video recordings +--- + +
+
+ Event Video Playback +

Event Video Playback

+

Transform TwinCAT Vision images into event-driven video recordings

+ +
+
+ +
+
+
+

Powerful Features for Industrial Automation

+

Everything you need to capture, log, and review event-driven video from TwinCAT Vision

+
+
+
+ 📹 +

Event-Driven Capture

+

Automatically capture and compile videos from TwinCAT Vision images when critical events occur. No manual intervention required.

+
+
+ 📊 +

Event Logging & HMI Playback

+

Seamlessly integrate with TwinCAT Event Logger for automatic video logging, then review and analyze recorded events directly from your HMI with intuitive playback controls.

+
+
+ 🔧 +

Easy PLC Integration

+

Simple-to-use PLC function blocks make integration into your existing TwinCAT projects quick and straightforward.

+
+
+
+
+ +
+
+
+
+

Why Event Video Playback?

+

In industrial automation, understanding what happened during critical events is crucial. Event Video Playback bridges the gap between TwinCAT Vision image capture and meaningful video documentation.

+

Real-World Example: When a machine down occurrence is triggered, the system automatically compiles recent images into a video, logs it with Event Logger, and makes it available for review on the HMI. Operators and engineers can quickly diagnose issues without manually searching through thousands of individual images.

+
+
+ Event Video Playback Overview +
+
+
+
+ +
+
+
+

System Requirements

+

Everything you need to get started with Event Video Playback

+
+
+
+ + TwinCAT 3.1 Build 4026 or higher +
+
+ + TwinCAT Vision Package
TwinCAT HMI Package
+
+
+ + Windows 10 or 11 +
+
+ +
+
+ +
+
+
+

Ready to Get Started?

+
+
+
+ 📦 +

Install With TwinCAT Package Manager

+

Quick installation using TwinCAT Package Manager for seamless integration with your TwinCAT environment.

+ Getting Started → +
+
+ 📖 +

PLC Developers

+

Learn how to integrate Event Video Playback function blocks into your TwinCAT PLC projects.

+ PLC Library Guide → +
+
+ 🖥️ +

HMI Developers

+

Add video playback controls to your HMI using the NuGet package for WPF applications.

+ HMI Package Guide → +
+
+ ⚙️ +

System Service Configuration

+

Configure the Windows service, set up video parameters, and troubleshoot installations.

+ Service Config → +
+
+
+
diff --git a/tcpkg/Push-Packages.ps1 b/tcpkg/Push-Packages.ps1 new file mode 100644 index 0000000..08747e9 --- /dev/null +++ b/tcpkg/Push-Packages.ps1 @@ -0,0 +1,80 @@ +# Push-Packages.ps1 +# Pushes all .nupkg files in the release directory to a specified package server + +# Set the working directory to the script's location +$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path +Set-Location $ScriptDir + +# Prompt for server URL +$serverUrl = Read-Host "Enter the package server URL (e.g., https://packages.beckhoff-usa-community.com/api/v2/package)" + +# Prompt for API key +Write-Host "Enter the API key (input will be visible):" -ForegroundColor Yellow +$apiKey = Read-Host + +# Validate inputs +if ([string]::IsNullOrWhiteSpace($serverUrl)) { + Write-Host "Error: Server URL cannot be empty" -ForegroundColor Red + exit 1 +} + +if ([string]::IsNullOrWhiteSpace($apiKey)) { + Write-Host "Error: API key cannot be empty" -ForegroundColor Red + exit 1 +} + +# Find all .nupkg files in the release directory +$packagesPath = Join-Path $ScriptDir "release" +$packages = Get-ChildItem -Path $packagesPath -Filter "*.nupkg" -File + +if ($packages.Count -eq 0) { + Write-Host "No .nupkg files found in $packagesPath" -ForegroundColor Yellow + exit 0 +} + +Write-Host "`nFound $($packages.Count) package(s) to push:" -ForegroundColor Green +$packages | ForEach-Object { Write-Host " - $($_.Name)" } + +# Ask for confirmation +$confirmation = Read-Host "`nDo you want to push these packages? (Y/N)" +if ($confirmation -ne 'Y' -and $confirmation -ne 'y') { + Write-Host "Operation cancelled" -ForegroundColor Yellow + exit 0 +} + +# Push each package +Write-Host "`nPushing packages..." -ForegroundColor Green +$successCount = 0 +$failCount = 0 + +foreach ($package in $packages) { + Write-Host "`nPushing $($package.Name)..." -ForegroundColor Cyan + + # Change to the release directory to push the package + Push-Location $packagesPath + + try { + & tcpkg push $package.Name -s="$serverUrl" -k="$apiKey" + + if ($LASTEXITCODE -eq 0) { + Write-Host " Successfully pushed $($package.Name)" -ForegroundColor Green + $successCount++ + } else { + Write-Host " Failed to push $($package.Name) (exit code: $LASTEXITCODE)" -ForegroundColor Red + $failCount++ + } + } catch { + Write-Host " Error pushing $($package.Name): $($_.Exception.Message)" -ForegroundColor Red + $failCount++ + } finally { + Pop-Location + } +} + +# Summary +Write-Host "`n========================================" -ForegroundColor Cyan +Write-Host "Push Summary:" -ForegroundColor Cyan +Write-Host " Total packages: $($packages.Count)" -ForegroundColor White +Write-Host " Successfully pushed: $successCount" -ForegroundColor Green +Write-Host " Failed: $failCount" -ForegroundColor $(if ($failCount -gt 0) { "Red" } else { "White" }) +Write-Host "========================================" -ForegroundColor Cyan diff --git a/tcpkg/packages/Beckhoff-USA-Community.Disclaimer/Beckhoff.Disclaimer.BetaFeed.nuspec b/tcpkg/packages/Beckhoff-USA-Community.Disclaimer/Beckhoff.Disclaimer.BetaFeed.nuspec new file mode 100644 index 0000000..fbf1cd8 --- /dev/null +++ b/tcpkg/packages/Beckhoff-USA-Community.Disclaimer/Beckhoff.Disclaimer.BetaFeed.nuspec @@ -0,0 +1,18 @@ + + + + Beckhoff.Disclaimer.BetaFeed + 1.0.0 + Beckhoff Disclaimer for Beta Feed + Beckhoff Automation + true + https://packages.beckhoff-usa-community.com/assets/Beckhoff.Disclaimer.BetaFeed/disclaimer/disclaimer.txt + https://www.beckhoff.com/en-us/products/automation/twincat/ + Disclaimer for Beta Feed + (c) Beckhoff Automation GmbH & Co. KG + disclaimer AS:AcceptBeta1.0.0:AS + + + + + \ No newline at end of file diff --git a/tcpkg/packages/Beckhoff-USA-Community.Disclaimer/disclaimer/disclaimer.txt b/tcpkg/packages/Beckhoff-USA-Community.Disclaimer/disclaimer/disclaimer.txt new file mode 100644 index 0000000..e9bcfb1 --- /dev/null +++ b/tcpkg/packages/Beckhoff-USA-Community.Disclaimer/disclaimer/disclaimer.txt @@ -0,0 +1,94 @@ +================================================================================ + ____ __ __ ________ + / __ )___ _____/ /__/ /_ ____ / __/ __/ + / __ / _ \/ ___/ //_/ __ \/ __ \/ /_/ /_ + / /_/ / __/ /__/ ,< / / / / /_/ / __/ __/ +/_____/\___/\___/_/|_/_/ /_/\____/_/ /_/ + / / / / ___// | + / / / /\__ \/ /| | +/ /_/ /___/ / ___ | +\____//____/_/ |_| _ __ + / ____/___ ____ ___ ____ ___ __ ______ (_) /___ __ + / / / __ \/ __ `__ \/ __ `__ \/ / / / __ \/ / __/ / / / +/ /___/ /_/ / / / / / / / / / / / /_/ / / / / / /_/ /_/ / +\____/\____/_/ /_/ /_/_/ /_/ /_/\__,_/_/ /_/_/\__/\__, / + /____/ + + COMMUNITY PACKAGE FEED - IMPORTANT DISCLAIMER +================================================================================ + +WELCOME TO THE BECKHOFF USA COMMUNITY PACKAGE REPOSITORY + +This package feed provides open-source TwinCAT packages developed and +maintained by the Beckhoff USA Community. These packages are independently +created and shared to benefit the automation community. + +================================================================================ + AGREEMENT TO TERMS +================================================================================ + +By adding this package feed to your TwinCAT Package Manager and installing +any packages from packages.beckhoff-usa-community.com, you acknowledge and +agree to the terms outlined in this disclaimer. + +================================================================================ + PACKAGE SIGNATURE VERIFICATION +================================================================================ + +IMPORTANT: Package signing verification must be disabled to use this feed. + +TwinCAT Package Manager currently only supports package signing from official +Beckhoff Automation GmbH & Co. KG package feeds. Community packages are not +signed by Beckhoff. + +To disable signature verification, run this command in an ELEVATED PowerShell: + + tcpkg config unset -n VerifySignatures + +================================================================================ + DISCLAIMER OF WARRANTIES +================================================================================ + +All sample code provided by the Beckhoff-USA-Community repositories and +distributed on packages.beckhoff-usa-community.com feeds, as well as sample +code provided by Beckhoff Automation LLC, are for illustrative purposes only +and are provided "as is" and without any warranties, express or implied. + +Actual implementations in applications will vary significantly. + +Beckhoff Automation LLC shall have no liability for, and does not waive any +rights in relation to, any code samples that it provides or the use of such +code samples for any purpose. + +Community packages are independently maintained and provided without +warranties. Review all code and licenses before use in production +environments. + +================================================================================ + LICENSE INFORMATION +================================================================================ + +Each repository in the Beckhoff-USA-Community GitHub organization maintains +its own license terms. You MUST read and understand the individual license +for each specific package before use. + +License terms may vary between packages. It is your responsibility to ensure +compliance with the applicable license for any package you use. + +================================================================================ + SUPPORT & ASSISTANCE +================================================================================ + +For support, issues, or questions regarding community packages: + +1. Visit the specific package repository on GitHub +2. Post your question or issue in the GitHub Issue Tracker +3. Community maintainers will respond when available + +Repository: https://github.com/Beckhoff-USA-Community + +================================================================================ + +Thank you for being part of the Beckhoff USA Community! + +================================================================================ diff --git a/tcpkg/packages/EventVideoPlayback.Library/EventVideoPlayback.Library.nuspec b/tcpkg/packages/EventVideoPlayback.Library/EventVideoPlayback.Library.nuspec index 81a68a7..bf3c1b2 100644 --- a/tcpkg/packages/EventVideoPlayback.Library/EventVideoPlayback.Library.nuspec +++ b/tcpkg/packages/EventVideoPlayback.Library/EventVideoPlayback.Library.nuspec @@ -1,17 +1,19 @@ - + Beckhoff-USA-Community.XAE.PLC.Lib.EventVideoPlayback 1.1.1 - https://github.com/Beckhoff-USA-Community/EventVideoPlayback + EventVideoPlayback PLC Library Beckhoff Automation LLC https://github.com/Beckhoff-USA-Community/EventVideoPlayback (c) Beckhoff Automation LLC true - LICENSE.md - icon.png + https://packages.beckhoff-usa-community.com/assets/EventVideoPlayback.Library/LICENSE.txt + https://packages.beckhoff-usa-community.com/assets/EventVideoPlayback.Library/icon.png docs/README.md - Beckhoff TwinCAT AllowMultipleVersions EventVideoPlayback + PLC library for Event Video Playback system integration + Beckhoff TwinCAT AllowMultipleVersions + Version 1.1.1 - Compatible with EventVideoPlayback 2.0.0 EventVideoPlayback PLC Library - TwinCAT 3 library for video playback event management. @@ -19,10 +21,8 @@ - - diff --git a/tcpkg/packages/EventVideoPlayback.Library/icon.png b/tcpkg/packages/EventVideoPlayback.Library/package-icon.png similarity index 100% rename from tcpkg/packages/EventVideoPlayback.Library/icon.png rename to tcpkg/packages/EventVideoPlayback.Library/package-icon.png diff --git a/tcpkg/packages/EventVideoPlayback.Library/pages/Camera_Hero_NoBackground.png b/tcpkg/packages/EventVideoPlayback.Library/pages/Camera_Hero_NoBackground.png new file mode 100644 index 0000000..c8d1146 Binary files /dev/null and b/tcpkg/packages/EventVideoPlayback.Library/pages/Camera_Hero_NoBackground.png differ diff --git a/tcpkg/packages/EventVideoPlayback.Service/EventVideoPlayback.Service.nuspec b/tcpkg/packages/EventVideoPlayback.Service/EventVideoPlayback.Service.nuspec index 8dd1ccf..8f545a3 100644 --- a/tcpkg/packages/EventVideoPlayback.Service/EventVideoPlayback.Service.nuspec +++ b/tcpkg/packages/EventVideoPlayback.Service/EventVideoPlayback.Service.nuspec @@ -1,27 +1,27 @@ - + Beckhoff-USA-Community.XAR.Service.EventVideoPlayback 2.0.0 - https://github.com/Beckhoff-USA-Community/EventVideoPlayback + EventVideoPlayback System Service Beckhoff Automation LLC https://github.com/Beckhoff-USA-Community/EventVideoPlayback (c) Beckhoff Automation LLC true - LICENSE.md - icon.png + https://packages.beckhoff-usa-community.com/assets/EventVideoPlayback.Service/LICENSE.txt + https://packages.beckhoff-usa-community.com/assets/EventVideoPlayback.Service/icon.png docs/README.md - Beckhoff TwinCAT AllowMultipleVersions EventVideoPlayback - Beckhoff Setup SystemServiceRestart + EventVideoPlayback runtime system service for TwinCAT XAR + Beckhoff Setup SystemServiceRestart + Version 2.0.0 - EventVideoPlayback system service for runtime deployment + EventVideoPlayback System Service - Windows service for video playback event management on TwinCAT runtime systems. - - diff --git a/tcpkg/packages/EventVideoPlayback.Service/icon.png b/tcpkg/packages/EventVideoPlayback.Service/package-icon.png similarity index 100% rename from tcpkg/packages/EventVideoPlayback.Service/icon.png rename to tcpkg/packages/EventVideoPlayback.Service/package-icon.png diff --git a/tcpkg/packages/EventVideoPlayback.XAE/EventVideoPlayback.XAE.Workload.nuspec b/tcpkg/packages/EventVideoPlayback.XAE/EventVideoPlayback.XAE.Workload.nuspec index a7a2f75..864529c 100644 --- a/tcpkg/packages/EventVideoPlayback.XAE/EventVideoPlayback.XAE.Workload.nuspec +++ b/tcpkg/packages/EventVideoPlayback.XAE/EventVideoPlayback.XAE.Workload.nuspec @@ -1,49 +1,31 @@ - - Beckhoff-USA-Community.XAE.EventVideoPlayback - - + Beckhoff-USA-Community.EventVideoPlayback.XAE 2.0.0 - - Event Video Playback - - Beckhoff Automation LLC - true - LICENSE.md - icon.png + https://packages.beckhoff-usa-community.com/assets/EventVideoPlayback.XAE/LICENSE.txt + https://packages.beckhoff-usa-community.com/assets/EventVideoPlayback.XAE/icon.png docs/README.md https://github.com/Beckhoff-USA-Community/EventVideoPlayback - - - A workload package containing Event Video Playback System Service, PLC Library, HMI Control, and Documentation - - + + This workload contains the Event Video Playback system service, documentation, PLC library, and HMI user control. + (c) Beckhoff Automation LLC - - - Beckhoff TwinCAT Workload CategoryGeneral VariantXAE - - + Beckhoff TwinCAT Workload CategoryBeckhoff USA Community | Vision VariantXAE - - - - - + diff --git a/tcpkg/packages/EventVideoPlayback.XAE/docs/README.md b/tcpkg/packages/EventVideoPlayback.XAE/docs/README.md index d1f83ea..f38a1d6 100644 --- a/tcpkg/packages/EventVideoPlayback.XAE/docs/README.md +++ b/tcpkg/packages/EventVideoPlayback.XAE/docs/README.md @@ -26,7 +26,7 @@ tcpkg install Beckhoff-USA-Community.XAE.EventVideoPlayback ## Requirements -- TwinCAT 3 XAE (Build 4024 or higher) +- TwinCAT 3 XAE (Build 4026 or higher) - TF7xxx Vision License - TE2000 HMI Engineering (optional, for HMI components) diff --git a/docs/images/EventVideoPlayback_64x64.png b/tcpkg/packages/EventVideoPlayback.XAE/workload-icon.png similarity index 100% rename from docs/images/EventVideoPlayback_64x64.png rename to tcpkg/packages/EventVideoPlayback.XAE/workload-icon.png diff --git a/tcpkg/packages/EventVideoPlayback.XAR/EventVideoPlayback.XAR.Workload.nuspec b/tcpkg/packages/EventVideoPlayback.XAR/EventVideoPlayback.XAR.Workload.nuspec index a2a6716..94a0022 100644 --- a/tcpkg/packages/EventVideoPlayback.XAR/EventVideoPlayback.XAR.Workload.nuspec +++ b/tcpkg/packages/EventVideoPlayback.XAR/EventVideoPlayback.XAR.Workload.nuspec @@ -1,47 +1,29 @@ - - Beckhoff-USA-Community.XAR.EventVideoPlayback - - + Beckhoff-USA-Community.EventVideoPlayback.XAR 2.0.0 - - Event Video Playback - - Beckhoff Automation LLC - true - LICENSE.md - icon.png + https://packages.beckhoff-usa-community.com/assets/EventVideoPlayback.XAR/LICENSE.txt + https://packages.beckhoff-usa-community.com/assets/EventVideoPlayback.XAR/icon.png docs/README.md https://github.com/Beckhoff-USA-Community/EventVideoPlayback - - - A workload package containing E.V.P system service - - + + This workload contains the Event Video Playback system service, documentation, PLC library, and HMI user control. + (c) Beckhoff Automation LLC - - - Beckhoff TwinCAT Workload CategoryGeneral VariantXAR - - + Beckhoff TwinCAT Workload CategoryBeckhoff USA Community | Vision VariantXAR - - - - diff --git a/tcpkg/packages/EventVideoPlayback.XAE/icon.png b/tcpkg/packages/EventVideoPlayback.XAR/workload-icon.png similarity index 100% rename from tcpkg/packages/EventVideoPlayback.XAE/icon.png rename to tcpkg/packages/EventVideoPlayback.XAR/workload-icon.png diff --git a/tcpkg/packages/EventVision.HMI/EventVision.HMI.nuspec b/tcpkg/packages/EventVision.HMI/EventVision.HMI.nuspec index 50d62b5..38e2901 100644 --- a/tcpkg/packages/EventVision.HMI/EventVision.HMI.nuspec +++ b/tcpkg/packages/EventVision.HMI/EventVision.HMI.nuspec @@ -1,5 +1,5 @@ - + Beckhoff-USA-Community.XAE.HMI.EventVisionControl 1.1.3 @@ -8,20 +8,20 @@ https://github.com/Beckhoff-USA-Community/EventVideoPlayback (c) Beckhoff Automation LLC true - LICENSE.md - icon.png + https://packages.beckhoff-usa-community.com/assets/EventVision.HMI/LICENSE.txt + https://packages.beckhoff-usa-community.com/assets/EventVision.HMI/icon.png docs/README.md - Beckhoff TwinCAT AllowMultipleVersions EventVideoPlayback NuGet HMI + EventVision HMI control for TwinCAT HMI integration + Beckhoff TwinCAT AllowMultipleVersions + Version 1.1.3 - HMI control for EventVision video display EventVision HMI Package - TwinCAT HMI components for EventVideoPlayback system. This package installs the HMI NuGet package to the Beckhoff NuGet packages directory. - - diff --git a/tcpkg/packages/EventVision.HMI/icon.png b/tcpkg/packages/EventVision.HMI/package-icon.png similarity index 100% rename from tcpkg/packages/EventVision.HMI/icon.png rename to tcpkg/packages/EventVision.HMI/package-icon.png diff --git a/tcpkg/packages/EventvideoPlayback.Documentation/EventVideoPlayback.Documentation.nuspec b/tcpkg/packages/EventvideoPlayback.Documentation/EventVideoPlayback.Documentation.nuspec index d526d0e..7a1ca90 100644 --- a/tcpkg/packages/EventvideoPlayback.Documentation/EventVideoPlayback.Documentation.nuspec +++ b/tcpkg/packages/EventvideoPlayback.Documentation/EventVideoPlayback.Documentation.nuspec @@ -1,25 +1,24 @@ - + Beckhoff-USA-Community.XAE.Documentation.EventVideoPlayback 2.0.0 Event Video Playback Documentation Beckhoff Automation LLC + https://github.com/Beckhoff-USA-Community/EventVideoPlayback (c) Beckhoff Automation LLC true - LICENSE.md - icon.png + https://packages.beckhoff-usa-community.com/assets/EventVideoPlayback.Documentation/LICENSE.txt + https://packages.beckhoff-usa-community.com/assets/EventVideoPlayback.Documentation/icon.png docs/README.md - https://github.com/Beckhoff-USA-Community/EventVideoPlayback - icon.png - Beckhoff TwinCAT AllowMultipleVersions EventVideoPlayback Documentation + Documentation and examples for EventVideoPlayback system + Beckhoff TwinCAT + Version 2.0.0 - Complete documentation for EventVideoPlayback 2.0 release EventVideoPlayback Documentation Package - Comprehensive documentation for the EventVideoPlayback system including installation guides, usage instructions, system requirements, and service documentation. - - diff --git a/tcpkg/packages/EventvideoPlayback.Documentation/icon.png b/tcpkg/packages/EventvideoPlayback.Documentation/package-icon.png similarity index 100% rename from tcpkg/packages/EventvideoPlayback.Documentation/icon.png rename to tcpkg/packages/EventvideoPlayback.Documentation/package-icon.png diff --git a/tcpkg/packages/assets/Beckhoff.Disclaimer.BetaFeed/disclaimer/disclaimer.txt b/tcpkg/packages/assets/Beckhoff.Disclaimer.BetaFeed/disclaimer/disclaimer.txt new file mode 100644 index 0000000..5e8cee6 --- /dev/null +++ b/tcpkg/packages/assets/Beckhoff.Disclaimer.BetaFeed/disclaimer/disclaimer.txt @@ -0,0 +1,79 @@ +================================================================================ + COMMUNITY PACKAGE FEED - IMPORTANT DISCLAIMER +================================================================================ + +WELCOME TO THE BECKHOFF USA COMMUNITY PACKAGE REPOSITORY + +This package feed provides open-source TwinCAT packages developed and +maintained by the Beckhoff USA Community. These packages are independently +created and shared to benefit the automation community. + +================================================================================ + AGREEMENT TO TERMS +================================================================================ + +By adding this package feed to your TwinCAT Package Manager and installing +any packages from packages.beckhoff-usa-community.com, you acknowledge and +agree to the terms outlined in this disclaimer. + +================================================================================ + PACKAGE SIGNATURE VERIFICATION +================================================================================ + +IMPORTANT: Package signing verification must be disabled to use this feed. + +TwinCAT Package Manager currently only supports package signing from official +Beckhoff Automation GmbH & Co. KG package feeds. Community packages are not +signed by Beckhoff. + +To disable signature verification, run this command in an ELEVATED PowerShell: + + tcpkg config unset -n VerifySignatures + +================================================================================ + DISCLAIMER OF WARRANTIES +================================================================================ + +All sample code provided by the Beckhoff-USA-Community repositories and +distributed on packages.beckhoff-usa-community.com feeds, as well as sample +code provided by Beckhoff Automation LLC, are for illustrative purposes only +and are provided "as is" and without any warranties, express or implied. + +Actual implementations in applications will vary significantly. + +Beckhoff Automation LLC shall have no liability for, and does not waive any +rights in relation to, any code samples that it provides or the use of such +code samples for any purpose. + +Community packages are independently maintained and provided without +warranties. Review all code and licenses before use in production +environments. + +================================================================================ + LICENSE INFORMATION +================================================================================ + +Each repository in the Beckhoff-USA-Community GitHub organization maintains +its own license terms. You MUST read and understand the individual license +for each specific package before use. + +License terms may vary between packages. It is your responsibility to ensure +compliance with the applicable license for any package you use. + +================================================================================ + SUPPORT & ASSISTANCE +================================================================================ + +For support, issues, or questions regarding community packages: + +1. Visit the specific package repository on GitHub +2. Post your question or issue in the GitHub Issue Tracker +3. Community maintainers will respond when available + +Repository: https://github.com/Beckhoff-USA-Community + +================================================================================ + +Thank you for being part of the Beckhoff USA Community! + +================================================================================ diff --git a/tcpkg/packages/assets/EventVideoPlayback.Documentation/LICENSE.txt b/tcpkg/packages/assets/EventVideoPlayback.Documentation/LICENSE.txt new file mode 100644 index 0000000..d5de80a --- /dev/null +++ b/tcpkg/packages/assets/EventVideoPlayback.Documentation/LICENSE.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Beckhoff Automation LLC + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/tcpkg/packages/assets/EventVideoPlayback.Documentation/icon.png b/tcpkg/packages/assets/EventVideoPlayback.Documentation/icon.png new file mode 100644 index 0000000..cb2773d Binary files /dev/null and b/tcpkg/packages/assets/EventVideoPlayback.Documentation/icon.png differ diff --git a/tcpkg/packages/assets/EventVideoPlayback.Library/LICENSE.txt b/tcpkg/packages/assets/EventVideoPlayback.Library/LICENSE.txt new file mode 100644 index 0000000..d5de80a --- /dev/null +++ b/tcpkg/packages/assets/EventVideoPlayback.Library/LICENSE.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Beckhoff Automation LLC + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/tcpkg/packages/assets/EventVideoPlayback.Library/icon.png b/tcpkg/packages/assets/EventVideoPlayback.Library/icon.png new file mode 100644 index 0000000..cb2773d Binary files /dev/null and b/tcpkg/packages/assets/EventVideoPlayback.Library/icon.png differ diff --git a/tcpkg/packages/assets/EventVideoPlayback.Service/LICENSE.txt b/tcpkg/packages/assets/EventVideoPlayback.Service/LICENSE.txt new file mode 100644 index 0000000..edbb5e6 --- /dev/null +++ b/tcpkg/packages/assets/EventVideoPlayback.Service/LICENSE.txt @@ -0,0 +1,115 @@ +# License + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +--- + +## EventVideoPlayback License + +**Copyright (c) 2023 Beckhoff Automation LLC** + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +--- + +## OpenH264 Codec License + +**Copyright (c) 2013, Cisco Systems** +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +--- + +## OpenCV License + +**Apache License Version 2.0, January 2004** +http://www.apache.org/licenses/ + +### TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +#### 1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. + +"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. + +#### 2. Grant of Copyright License. + +Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. + +#### 3. Grant of Patent License. + +Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. + +#### 4. Redistribution. + +You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: + +(a) You must give any other recipients of the Work or Derivative Works a copy of this License; and + +(b) You must cause any modified files to carry prominent notices stating that You changed the files; and + +(c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and + +(d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. + +You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. + +#### 5. Submission of Contributions. + +Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. + +#### 6. Trademarks. + +This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. + +#### 7. Disclaimer of Warranty. + +Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. + +#### 8. Limitation of Liability. + +In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. + +#### 9. Accepting Warranty or Additional Liability. + +While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. + +### END OF TERMS AND CONDITIONS + +### APPENDIX: How to apply the Apache License to your work. + +To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. + +**Copyright 2008 shimat** + +Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. diff --git a/tcpkg/packages/assets/EventVideoPlayback.Service/icon.png b/tcpkg/packages/assets/EventVideoPlayback.Service/icon.png new file mode 100644 index 0000000..cb2773d Binary files /dev/null and b/tcpkg/packages/assets/EventVideoPlayback.Service/icon.png differ diff --git a/tcpkg/packages/assets/EventVideoPlayback.XAE/LICENSE.txt b/tcpkg/packages/assets/EventVideoPlayback.XAE/LICENSE.txt new file mode 100644 index 0000000..d5de80a --- /dev/null +++ b/tcpkg/packages/assets/EventVideoPlayback.XAE/LICENSE.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Beckhoff Automation LLC + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/tcpkg/packages/EventVideoPlayback.XAR/icon.png b/tcpkg/packages/assets/EventVideoPlayback.XAE/icon.png similarity index 100% rename from tcpkg/packages/EventVideoPlayback.XAR/icon.png rename to tcpkg/packages/assets/EventVideoPlayback.XAE/icon.png diff --git a/tcpkg/packages/assets/EventVideoPlayback.XAR/LICENSE.txt b/tcpkg/packages/assets/EventVideoPlayback.XAR/LICENSE.txt new file mode 100644 index 0000000..edbb5e6 --- /dev/null +++ b/tcpkg/packages/assets/EventVideoPlayback.XAR/LICENSE.txt @@ -0,0 +1,115 @@ +# License + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +--- + +## EventVideoPlayback License + +**Copyright (c) 2023 Beckhoff Automation LLC** + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +--- + +## OpenH264 Codec License + +**Copyright (c) 2013, Cisco Systems** +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +--- + +## OpenCV License + +**Apache License Version 2.0, January 2004** +http://www.apache.org/licenses/ + +### TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +#### 1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. + +"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. + +#### 2. Grant of Copyright License. + +Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. + +#### 3. Grant of Patent License. + +Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. + +#### 4. Redistribution. + +You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: + +(a) You must give any other recipients of the Work or Derivative Works a copy of this License; and + +(b) You must cause any modified files to carry prominent notices stating that You changed the files; and + +(c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and + +(d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. + +You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. + +#### 5. Submission of Contributions. + +Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. + +#### 6. Trademarks. + +This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. + +#### 7. Disclaimer of Warranty. + +Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. + +#### 8. Limitation of Liability. + +In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. + +#### 9. Accepting Warranty or Additional Liability. + +While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. + +### END OF TERMS AND CONDITIONS + +### APPENDIX: How to apply the Apache License to your work. + +To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. + +**Copyright 2008 shimat** + +Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. diff --git a/tcpkg/packages/assets/EventVideoPlayback.XAR/icon.png b/tcpkg/packages/assets/EventVideoPlayback.XAR/icon.png new file mode 100644 index 0000000..21ed06b Binary files /dev/null and b/tcpkg/packages/assets/EventVideoPlayback.XAR/icon.png differ diff --git a/tcpkg/packages/assets/EventVision.HMI/LICENSE.txt b/tcpkg/packages/assets/EventVision.HMI/LICENSE.txt new file mode 100644 index 0000000..d5de80a --- /dev/null +++ b/tcpkg/packages/assets/EventVision.HMI/LICENSE.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Beckhoff Automation LLC + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/tcpkg/packages/assets/EventVision.HMI/icon.png b/tcpkg/packages/assets/EventVision.HMI/icon.png new file mode 100644 index 0000000..cb2773d Binary files /dev/null and b/tcpkg/packages/assets/EventVision.HMI/icon.png differ diff --git a/tcpkg/release/checksums.md b/tcpkg/release/checksums.md index 99af2dd..6bf4b71 100644 --- a/tcpkg/release/checksums.md +++ b/tcpkg/release/checksums.md @@ -1,6 +1,6 @@ # TwinCAT Package Checksums -**Generated:** 2025-10-28 12:54:36 +**Generated:** 2025-11-10 08:39:04 **Release Folder:** C:\GitHub\EventVideoPlayback\tcpkg\.\release This file contains SHA256 checksums for all built packages to ensure integrity and traceability. @@ -9,12 +9,13 @@ This file contains SHA256 checksums for all built packages to ensure integrity a | Package Name | Version | SHA256 Checksum | |--------------|---------|-----------------| -| Beckhoff-USA-Community.XAE.Documentation.EventVideoPlayback | 2.0.0 | `B3613FC56E6EBB407D520CA0B7A0E0E696CCEDA9031EDD1431C1A2B200C20974` | -| Beckhoff-USA-Community.XAE.EventVideoPlayback | 2.0.0 | `1519ED7182A18467741835B31481847728D174802082AFF77CCBD712671A0937` | -| Beckhoff-USA-Community.XAE.HMI.EventVisionControl | 1.1.3 | `CAA7EC75E838F87034E4C77E198140027B759751FE3AFF25111DA2717E6FC77B` | -| Beckhoff-USA-Community.XAE.PLC.Lib.EventVideoPlayback | 1.1.1 | `06B94CD1D5CA2D5459340EC299393DDE4CB9BB443D43675ADAC18FB0001870BE` | -| Beckhoff-USA-Community.XAR.EventVideoPlayback | 2.0.0 | `875E4F37FE1D15F39DE1EBFCDB62249956E9D997000D7BC42A3CA9C6C057F355` | -| Beckhoff-USA-Community.XAR.Service.EventVideoPlayback | 2.0.0 | `09315B42D8E298669A1542FE81C1C090B3B33FB731308C2B05F4401DE2C48B79` | +| Beckhoff-USA-Community.EventVideoPlayback.XAE | 2.0.0 | `E3D29512A7F60977E2038F2F97777E913339E81AEB72FFC17769C208C317B2DB` | +| Beckhoff-USA-Community.EventVideoPlayback.XAR | 2.0.0 | `301C5BD8BCB1805E71776B5C332ADF707F2EE58053A0C5492FD961BA2625C286` | +| Beckhoff-USA-Community.XAE.Documentation.EventVideoPlayback | 2.0.0 | `64131561E0EC94E69DF52FCBBF564E003E906561D75A69E640151EF5098A4EF9` | +| Beckhoff-USA-Community.XAE.HMI.EventVisionControl | 1.1.3 | `358440528A73FB627340766FE11300F00E598FFA52EE459851EAB5A32836368B` | +| Beckhoff-USA-Community.XAE.PLC.Lib.EventVideoPlayback | 1.1.1 | `24BFE0AED289F0CF80294C0EE43064ACB040C4B44D10C4D1E80C1BC01DBBE470` | +| Beckhoff-USA-Community.XAR.Service.EventVideoPlayback | 2.0.0 | `97296EF0B207DEFFA13625DDF8C147AC42A19FF9CC0C8F6014F9368F896876D5` | +| Beckhoff.Disclaimer.BetaFeed | 1.0.0 | `45991EBCC3FD10760C73A406C33EC63B2D3ECF9E50B2C8108465D6D9DC09793D` | ## Verification Instructions