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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions .github/workflows/Build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,24 @@ jobs:
xcopy "T3000Webview\dist\spa\" "T3000 Output\release\ResourceFile\webview\www\" /E /H /C /I /y
xcopy "T3000Webview\api\target\i686-pc-windows-msvc\release\t3_webview_api.dll" "T3000 Output\release\" /Y
xcopy "T3000Webview\api\target\i686-pc-windows-msvc\release\t3_webview_api.dll.lib" "T3000 Output\release\" /Y
# CCTV UI. Sidecar exes are optional MIT processes (go2rtc / MediaMTX),
# never linked into T3000.exe. T3000.aip is unchanged; AddFolder of the
# release tree already installs whatever is under T3000 Output\release.
xcopy "T3000\ResourceFile\nvr\" "T3000 Output\release\ResourceFile\nvr\" /E /H /C /I /y
if exist "T3000\sidecar\go2rtc.exe" (
if not exist "T3000 Output\release\sidecar" mkdir "T3000 Output\release\sidecar"
copy /Y "T3000\sidecar\go2rtc.exe" "T3000 Output\release\sidecar\"
)
if exist "T3000\sidecar\mediamtx.exe" (
if not exist "T3000 Output\release\sidecar" mkdir "T3000 Output\release\sidecar"
copy /Y "T3000\sidecar\mediamtx.exe" "T3000 Output\release\sidecar\"
)

- name: Fetch CCTV sidecars (optional MIT exes for the MSI)
continue-on-error: true
shell: pwsh
run: |
powershell -ExecutionPolicy Bypass -File tools\fetch-nvr-sidecars.ps1 -OutDir "T3000 Output\release\sidecar"

# -----------------------------------------------------------------------
# SIGNING - origin-verification-compliant approach
Expand Down Expand Up @@ -125,6 +143,7 @@ jobs:
# Excluded (3rd-party, not owned by Temco):
# sqlite3.dll - SQLite Consortium
# WebView2Loader.dll - Microsoft
# sidecar\go2rtc.exe / mediamtx.exe - MIT sidecars, not linked into T3000.exe

$missing = @()
foreach ($file in $filesToSign) {
Expand Down
17 changes: 17 additions & 0 deletions .github/workflows/Release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,23 @@ jobs:
xcopy "T3000Webview\dist\spa\" "T3000 Output\release\ResourceFile\webview\www\" /E /H /C /I /y
xcopy "T3000Webview\api\target\i686-pc-windows-msvc\release\t3_webview_api.dll" "T3000 Output\release\" /Y
xcopy "T3000Webview\api\target\i686-pc-windows-msvc\release\t3_webview_api.dll.lib" "T3000 Output\release\" /Y
# CCTV UI. Sidecar exes are optional MIT processes (go2rtc / MediaMTX).
# T3000.aip is unchanged; AddFolder of the release tree installs this folder.
xcopy "T3000\ResourceFile\nvr\" "T3000 Output\release\ResourceFile\nvr\" /E /H /C /I /y
if exist "T3000\sidecar\go2rtc.exe" (
if not exist "T3000 Output\release\sidecar" mkdir "T3000 Output\release\sidecar"
copy /Y "T3000\sidecar\go2rtc.exe" "T3000 Output\release\sidecar\"
)
if exist "T3000\sidecar\mediamtx.exe" (
if not exist "T3000 Output\release\sidecar" mkdir "T3000 Output\release\sidecar"
copy /Y "T3000\sidecar\mediamtx.exe" "T3000 Output\release\sidecar\"
)

- name: Fetch CCTV sidecars (optional MIT exes for the MSI)
continue-on-error: true
shell: pwsh
run: |
powershell -ExecutionPolicy Bypass -File tools\fetch-nvr-sidecars.ps1 -OutDir "T3000 Output\release\sidecar"

# -----------------------------------------------------------------------
# PE SIGNING (origin-verification-compliant)
Expand Down
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -953,3 +953,7 @@ build/ALL_BUILD.vcxproj
/.vs
/T3000/Database
T3000Controls/project.lock.json

# CCTV sidecar binaries (downloaded; MIT, not vendored)
T3000/sidecar/*.exe
T3000/sidecar/*.zip
179 changes: 179 additions & 0 deletions DEMO.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
# T3000 CCTV — Windows teammate demo

**This branch is for a live demo on a normal T3000 Windows box. Do not merge until people have seen it running.**

The Linux cloud agent that opened the PR **cannot** start T3000.exe, WebView2, or a LAN camera. Follow these steps on your VS2019 machine. There is no special installer and you do not need master.

Developer background: [Documentation/nvr.md](Documentation/nvr.md).

---

## 1. Check out this branch and build (same as the rest of T3000)

```bat
git fetch origin
git checkout CCTV
```

1. Open **`T3000 - VS2019.sln`** in Visual Studio 2019.
2. Toolbar: configuration **Release** (or Debug), platform **Win32**.
3. **Build → Build Solution** (Ctrl+Shift+B).

Same MFC / x86 / requireAdministrator path as always. Sidecar `.exe` files are **not** required to compile. If the build fails, it is a normal T3000 compile error — see [README_Build.md](README_Build.md).

**Ignore the red GitHub check named “Testing the MSBuild” on this PR.** That workflow has been failing on `master` as well (missing MFC and .NET Framework 4.5.2 targeting pack on `windows-latest`). It dies before compiling `T3000NvrSidecar.cpp`. Your local VS2019 box is the real build.

Built app:

| Config | T3000.exe |
| --- | --- |
| Release | `T3000 Output\release\T3000.exe` |
| Debug | `T3000 Output\debug\T3000.exe` |

Post-build already copies `T3000\ResourceFile\nvr\index.html` next to that exe.

You also need the **Microsoft Edge WebView2 Runtime** (same as HVAC graphics / Modbus Register v2). If CCTV warns that it is missing, install it from https://developer.microsoft.com/en-us/microsoft-edge/webview2/ then retry.

---

## 2. Drop `go2rtc.exe` where the launcher will find it

Live video needs **go2rtc** (MIT, separate process, 64-bit is fine). **MediaMTX is optional** for this demo.

### Official Windows zips (no script required)

1. Download **[go2rtc_win64.zip](https://github.com/AlexxIT/go2rtc/releases/download/v1.9.14/go2rtc_win64.zip)** from [go2rtc v1.9.14](https://github.com/AlexxIT/go2rtc/releases/tag/v1.9.14).
2. Unzip. Copy **`go2rtc.exe`** to **any one** of these folders (create `sidecar` if needed):

**Preferred (no rebuild):** next to the exe you just built

```
T3000 Output\release\sidecar\go2rtc.exe
```

or simply

```
T3000 Output\release\go2rtc.exe
```

(Debug: the same under `T3000 Output\debug\`.)

**Also works:** source-tree folder (launcher walks `..\..\T3000\sidecar` from the output dir)

```
T3000\sidecar\go2rtc.exe
```

A Release post-build will also copy `T3000\sidecar\*.exe` into `T3000 Output\release\sidecar\` if they are already there.

### Optional MediaMTX (record/playback home, not needed for live view)

- Zip: **[mediamtx_v1.20.1_windows_amd64.zip](https://github.com/bluenviron/mediamtx/releases/download/v1.20.1/mediamtx_v1.20.1_windows_amd64.zip)**
- Drop `mediamtx.exe` in the **same** folder as `go2rtc.exe`.
- The CCTV header shows **MediaMTX :9197** when it is up, **MediaMTX off** when it is not. Live tiles still work.

### Optional: fetch script instead of a browser download

From the repo root, in PowerShell:

```powershell
powershell -ExecutionPolicy Bypass -File tools\fetch-nvr-sidecars.ps1
```

That writes `T3000\sidecar\go2rtc.exe` and `T3000\sidecar\mediamtx.exe`. Then either rebuild once, or copy those two files into `T3000 Output\release\sidecar\`.

**Do not commit the `.exe` files.**

---

## 3. Open the CCTV view

1. Run **`T3000.exe`** (the one you built — it will ask for Administrator, as usual).
2. Menu: **Tools → CCTV**.
3. A WebView2 window titled **CCTV** opens.

T3000 starts `go2rtc.exe` (and `mediamtx.exe` if present) on localhost, then loads `http://127.0.0.1:9191/index.html`. Closing that window stops processes T3000 started.

---

## 4. Point at a camera

The PC and the camera must be on the **same LAN** (ONVIF discovery uses multicast).

### Option A — ONVIF on the LAN

1. If the camera needs a login, type **Username** / **Password** first.
2. Click **Discover ONVIF**.
3. Wait a few seconds. Devices appear in the list (name + URL).
4. Click **Add** on the one you want.

### Option B — paste an RTSP URL (no ONVIF camera)

1. **Name:** e.g. `lobby`
2. **RTSP or ONVIF URL:** from the camera’s web UI, for example
`rtsp://admin:password@192.168.1.20/Streaming/Channels/101`
3. Click **Add and play**.

Any RTSP the Windows box can reach works (another recorder, a camera, a phone app that publishes RTSP). There is no fake “demo stream” bundled. Without a reachable URL you still see the CCTV UI and sidecar status, but no video.

WebView2 cannot play raw `rtsp://` inside a `<video>` tag. The page asks go2rtc for **WebRTC**, then **MP4**, then **MJPEG**.

---

## 5. What success looks like

- Header pills: **go2rtc :9191** (green). MediaMTX green only if you dropped that exe.
- Sidecar panel: something like “CCTV sidecar started (go2rtc on 127.0.0.1:9191).”
- After Add / Discover: a **live tile** with moving video (not a frozen snapshot).
- Status bar at the bottom of T3000 may repeat the sidecar message.

Close **CCTV**, reopen **Tools → CCTV** — saved cameras come back (WebView `localStorage` + `%LOCALAPPDATA%\T3000\nvr\cameras.json`).

---

## 6. What you should see if sidecar exes are missing

Leave `go2rtc.exe` out on purpose if you want to show this:

1. T3000 still starts and the rest of the app is unchanged.
2. **Tools → CCTV** still opens a CCTV window (no crash).
3. The sidecar panel is **red** and says `go2rtc.exe was not found. T3000 is running normally.`
4. It lists the folders to drop the file into, plus the official zip URL.
5. You can still use every other T3000 tool.

Drop `go2rtc.exe` into one of those folders, close CCTV, open it again — no reinstall.

---

## 7. Ports (localhost only — 9103 / 9104 / 3003 stay free)

| Process | Bind | Port | Used for |
| --- | --- | --- | --- |
| go2rtc | 127.0.0.1 | **9191** | CCTV page + API |
| go2rtc | 127.0.0.1 | 9192 | RTSP republish |
| go2rtc | 127.0.0.1 | 9193 | WebRTC |
| MediaMTX | 127.0.0.1 | 9194 / 9196 / 9197 | Optional; later record/playback |

Already taken by T3000 and **left alone**:

| Port | Owner |
| --- | --- |
| **9103** | Rust `t3_webview_api` HTTP |
| **9104** | Rust WebSocket |
| **3003** | Quasar / T3000Webview dev UI |

If something else already owns **9191** and it is not go2rtc, CCTV opens offline and tells you the port is in use.

Config written on each open: `%LOCALAPPDATA%\T3000\nvr\` (`go2rtc.yaml`, `mediamtx.yml`, `www\index.html`).

---

## Quick checklist for the person running the demo

- [ ] Branch `CCTV` built Win32 in VS2019
- [ ] `go2rtc.exe` sitting next to `T3000.exe` or in `sidecar\`
- [ ] **Tools → CCTV** opens
- [ ] Green **go2rtc :9191**
- [ ] ONVIF **Discover** or a pasted `rtsp://...` shows **live video**
- [ ] (Optional) Hide `go2rtc.exe` and reopen CCTV — red message, T3000 still works
2 changes: 2 additions & 0 deletions Documentation/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,7 @@ Technical plans, integration guides, and reference material for the T3000 Buildi

## Technical reference

- [CCTV Windows demo](../DEMO.md) — checkout, build, drop go2rtc, open Tools → CCTV, ONVIF/RTSP.
- [CCTV first slice](nvr.md) — go2rtc + MediaMTX sidecars, ports, CCTV WebView, installer notes.
- [WireGuard Modbus Register Map](WireGuard%20Modbus%20Register%20Map.md) — Modbus register interface for WireGuard VPN configuration on T3 ESP32 controllers.
- [Rebrand guide](rebrand.md) — How to extract custom names into `AppConfig.props` for software rebranding.
102 changes: 102 additions & 0 deletions Documentation/nvr.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
# T3000 CCTV (first slice)

**Windows demo (do not merge until teammates have seen it):** follow **[DEMO.md](../DEMO.md)** — checkout, VS2019 Win32 build, where to drop `go2rtc.exe`, Tools → CCTV, ONVIF/RTSP, success vs missing-exe.

Temco customers get cameras plus building automation in one T3000 install. v1 launches localhost sidecar processes, discovers ONVIF cameras, and shows live video in the existing WebView2 host. Motion detection, AI, mobile apps, full timeline playback, and cloud relay are out of scope.

T3000.exe stays 32-bit MFC. Sidecars are **separate processes** (64-bit is fine) talking HTTP on 127.0.0.1. Do not load go2rtc or MediaMTX as a DLL into T3000.exe.

## What we ship in this repo

| Piece | Location | Notes |
| --- | --- | --- |
| Launcher / lifecycle | `T3000/T3000NvrSidecar.cpp` | `CreateProcess`, job object, port checks |
| CCTV UI | `T3000/ResourceFile/nvr/index.html` | Self-contained page (T3000Webview is a submodule) |
| Menu entry | Tools → **CCTV** | Opens WebView2 |
| Fetch script | `tools/fetch-nvr-sidecars.ps1` | Downloads MIT binaries for devs / CI |
| Sidecar folder | `T3000/sidecar/` | Place `go2rtc.exe` and `mediamtx.exe` here |

Large binaries are **not** committed. The MSI picks them up only if they are copied into `T3000 Output\release\sidecar\` before Advanced Installer's `AddFolder` of the release tree.

## Sidecar bricks

| Binary | License | Role in v1 |
| --- | --- | --- |
| [go2rtc](https://github.com/AlexxIT/go2rtc) v1.9.14 | MIT | ONVIF discovery, RTSP ingest, WebRTC / MSE / MP4 live view |
| [MediaMTX](https://github.com/bluenviron/mediamtx) v1.20.1 | MIT | Layout + config for later record/playback. Optional for live view. |

FFmpeg is not shipped. Do not vendor GPL/AGPL NVR code (ZoneMinder, Moonfire, OpenNVR, motion) and do not statically link GPL into T3000.exe or `t3_webview_api.dll`.

## Obtain the sidecars (developers)

From a PowerShell prompt at the repo root:

```powershell
powershell -ExecutionPolicy Bypass -File tools\fetch-nvr-sidecars.ps1
```

This writes:

- `T3000\sidecar\go2rtc.exe`
- `T3000\sidecar\mediamtx.exe`

A VS2019 post-build step copies `ResourceFile\nvr\` to the output tree and, if present, `sidecar\*.exe` next to `T3000.exe`.

You can also drop the exes next to `T3000.exe` or under `nvr\`. Search order:

1. `{T3000.exe dir}\sidecar\go2rtc.exe` (same for `mediamtx.exe`)
2. `{T3000.exe dir}\go2rtc.exe`
3. `{T3000.exe dir}\nvr\go2rtc.exe`
4. `{T3000.exe dir}\..\..\T3000\sidecar\` (source tree when running from `T3000 Output\`)
5. `{T3000.exe dir}\..\T3000\sidecar\`

T3000 still builds and runs if the exes are missing. Opening CCTV shows a clear message in the WebView (see [DEMO.md](../DEMO.md) §6).

## Ports (127.0.0.1 only)

Do not use 9103 (Rust HTTP), 9104 (Rust WS), or 3003 (Quasar dev).

| Service | Port | Purpose |
| --- | --- | --- |
| go2rtc HTTP / API / UI | 9191 | Live view page + `/api` |
| go2rtc RTSP | 9192 | Local RTSP republish |
| go2rtc WebRTC | 9193 | WebRTC ICE |
| MediaMTX RTSP | 9194 | Future record ingest |
| MediaMTX playback | 9196 | Future VOD |
| MediaMTX API | 9197 | Health / later control |

## Config and user data

Generated under `%LOCALAPPDATA%\T3000\nvr\` (same LocalAppData root as WebView2's `T3000` user-data folder):

- `go2rtc.yaml` — rewritten on each CCTV launch
- `mediamtx.yml` — record/playback hook (`record` stays commented)
- `www\index.html` — copy of the CCTV page served by go2rtc `static_dir`
- `cameras.json` — persisted camera list (also kept in WebView `localStorage`)
- `recordings\` — reserved for MediaMTX

## How to open the view

1. Build T3000 (VS2019, Win32, Release or Debug) with or without sidecar exes.
2. Fetch or copy `go2rtc.exe` into `sidecar\` (and optionally `mediamtx.exe`).
3. Run T3000 and choose **Tools → CCTV**.
4. T3000 starts go2rtc (and MediaMTX if present), then opens WebView2 at `http://127.0.0.1:9191/index.html`.
5. Closing the CCTV window stops processes T3000 started. Exit of T3000 also stops them. An already-running go2rtc on 9191 is reused and not killed.

## Point at a camera

- **ONVIF:** click **Discover ONVIF**, enter credentials if needed, then **Add**.
- **RTSP:** set a name and URL such as `rtsp://user:pass@192.168.1.20/Streaming/Channels/101`, then **Add and play**.
- Live tiles prefer go2rtc WebRTC, then `/api/stream.mp4`, then MJPEG. WebView2 does not play raw RTSP.

## Installer / CI

`T3000.aip` is not edited (Advanced Installer projects are easy to break without a local test). `Build.yml` / `Release.yml`:

1. Copy `T3000\ResourceFile\nvr\` into `T3000 Output\release\ResourceFile\nvr\`.
2. Optionally run `tools/fetch-nvr-sidecars.ps1 -OutDir "T3000 Output\release\sidecar"` so the existing `AddFolder "APPDIR" ".\T3000 Output\release"` includes the MIT exes.
3. Do **not** add go2rtc/MediaMTX to the SignPath PE list (third-party, like sqlite).

## License isolation

T3000 remains MIT. go2rtc and MediaMTX remain separate MIT programs. Notices: `T3000/sidecar/NOTICE.txt`.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ T3000 Building Automation System

This is our T3000 Building Automation front end, a mature project for managing the air conditioning, lighting, access control and other automation functions of commercial buildings. The application runs on a Windows PC and allows the building operator to manage the building as a complete system. There is a small but growing team of developers working on the application full time. The system works mainly with Temco Controls products but integrators, controls contractors and other manufacturers are encouraged to join in to add their own devices and features. Communication is supported using Modbus and/or Bacnet calls over Ethernet, Wifi, RS485, RS232, and Bluetooth.

The project has been around for many years and has a bright future as the system and our application matures. We welcome contributions and suggestions on next steps. Please refer to [Wiki](https://github.com/temcocontrols/T3000_Building_Automation_System/wiki) for details on how you can get started with contributing towards the project. For build instructions see [Compile T3000](README_Build.md). See [Documentation](Documentation/README.md) for technical plans and integration guides.
The project has been around for many years and has a bright future as the system and our application matures. We welcome contributions and suggestions on next steps. Please refer to [Wiki](https://github.com/temcocontrols/T3000_Building_Automation_System/wiki) for details on how you can get started with contributing towards the project. For build instructions see [Compile T3000](README_Build.md). See [Documentation](Documentation/README.md) for technical plans and integration guides. CCTV Windows demo: [DEMO.md](DEMO.md). Details: [Documentation/nvr.md](Documentation/nvr.md).

To see how you can use our github release action in your own fork follow the instructions in our Wiki [How to use our github action to build the solution and the msi installer](https://github.com/temcocontrols/T3000_Building_Automation_System/wiki/How-to-use-our-github-action-to-build-the-solution-and-the-msi-installer)

Expand Down
14 changes: 14 additions & 0 deletions README_Build.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,20 @@ Launching a Build

Once the compilation is successful, the output files (executable, libraries, etc.) will be generated in the appropriate directory. By default, for the Release configuration, you can find the output files in the "Release" folder within your project directory.

CCTV sidecars (optional)
---------------------------------
Live view uses `go2rtc.exe` (and optionally `mediamtx.exe`) as localhost processes. They are not required to compile T3000.

**Windows teammate demo (this branch):** [DEMO.md](DEMO.md) — checkout, Win32 build, official zip links, Tools → CCTV, ONVIF/RTSP, missing-exe behavior.

Short version after a successful build:

```
powershell -ExecutionPolicy Bypass -File tools\fetch-nvr-sidecars.ps1
```

or drop `go2rtc.exe` from https://github.com/AlexxIT/go2rtc/releases/download/v1.9.14/go2rtc_win64.zip into `T3000 Output\release\sidecar\`. Then start T3000 and open **Tools → CCTV**.

* **Test the Application:**

Before distributing or using the compiled application, it's important to test it thoroughly to ensure it behaves as expected. Run the executable generated during the compilation to verify its functionality.
Expand Down
Loading
Loading