Skip to content
Open
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
17 changes: 10 additions & 7 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -412,17 +412,14 @@ jobs:
New-Item -ItemType Directory -Force -Path build\windows

$env:CGO_ENABLED = "1"
# Built with the "desktop" tag so the executable defaults to desktop
# mode: double-clicking device-simulator.exe opens the native window
# (no launcher .bat needed). Run with --desktop=false for headless mode.
go build -tags "desktop,production" `
-ldflags "-s -w -H windowsgui -X main.Version=$env:VERSION" `
-o build\windows\device-simulator.exe `
.\cmd\simulator\

# Create launcher batch file
@"
@echo off
start "" "%~dp0device-simulator.exe" --desktop %*
"@ | Out-File -FilePath build\windows\Device-Simulator.bat -Encoding ASCII

# Create zip (use consistent naming for selfupdate compatibility)
Compress-Archive -Path build\windows\* -DestinationPath build\device-simulator_windows_amd64.zip

Expand Down Expand Up @@ -483,5 +480,11 @@ jobs:
```

### Windows
1. Unzip and run `Device-Simulator.bat` or `device-simulator.exe --desktop`
1. Unzip and double-click `device-simulator.exe`
2. WebView2 will auto-install if needed

To run headless (HTTP server only, no window), open a terminal and run
`device-simulator.exe --desktop=false`, then browse to http://localhost:8762
Note: the released `.exe` is a GUI build, so it produces no console output and
Ctrl+C will not stop it — control it from the web dashboard, or use the Docker
image / `make build-windows-server` if you need console logs.
19 changes: 12 additions & 7 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,9 @@ go test ./...

```
device-simulator
├── Mode Selection (--desktop flag or WAILS_DESKTOP=1)
│ ├── Desktop Mode: Wails window + HTTP API on :8762
│ └── Server Mode: HTTP-only on :80 (Docker default)
├── Mode Selection (--desktop flag, build tag default, or WAILS_DESKTOP)
│ ├── Desktop Mode: Wails window + HTTP API on :8762 (default for desktop builds)
│ └── Server Mode: HTTP-only on :80 (default for server/Docker builds)
├── HTTP API Server (unified dashboard + REST API)
├── Modbus TCP Servers (:5000+)
├── MQTT Brokers (:1883+)
Expand All @@ -70,12 +70,17 @@ device-simulator

### Dual-Mode Operation

The app supports two modes controlled by the `--desktop` flag:
The app supports two modes controlled by the `--desktop` flag. The flag's
**default depends on the build tag**: builds compiled with the `desktop` tag
(the released macOS/Linux/Windows apps) default to desktop mode, so launching
the executable directly opens the native window. Server/Docker builds omit the
tag and default to headless. The default is defined in
`cmd/simulator/desktop_mode_on.go` / `desktop_mode_off.go`.

| Mode | Trigger | UI | Use Case |
|------|---------|-----|----------|
| Desktop | `--desktop` or `WAILS_DESKTOP=1` | Native Wails window | End users |
| Server | Default (no flag) | Browser at HTTP port | Docker, development |
| Desktop | `--desktop`, `WAILS_DESKTOP=1`, or a `desktop`-tagged build | Native Wails window | End users |
| Server | `--desktop=false`, `WAILS_DESKTOP=0`, or an untagged build | Browser at HTTP port | Docker, development |

### Go Backend (`cmd/simulator/`, `internal/`)

Expand Down Expand Up @@ -203,7 +208,7 @@ func (a *App) CheckForUpdate() (*UpdateInfo, error)
| MQTT_BASE_PORT | 1883 | First MQTT port |
| OCPP_BASE_PORT | 9000 | First OCPP port |
| HTTP_PORT | 80 (Docker) / 8762 (Desktop) | Web dashboard port |
| WAILS_DESKTOP | 0 | Set to 1 to force desktop mode |
| WAILS_DESKTOP | build-tag default | Set to 1 to force desktop mode, 0 to force headless (overrides --desktop) |
| HOST_IP | auto-detected | Override displayed host IP |

## CI/CD (GitHub Actions)
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@ sudo apt install libgtk-3-0 libwebkit2gtk-4.0-37 # Debian/Ubuntu
./linux/device-simulator.sh
```

**Windows:** Unzip and run `device-simulator.exe --desktop`
**Windows:** Unzip and double-click `device-simulator.exe` — the desktop window opens automatically (WebView2 auto-installs if needed).

> **Run headless on Windows?** Open a terminal and run `device-simulator.exe --desktop=false`, then browse to <http://localhost:8762>. (The released `.exe` is a GUI build, so it does not print to the console; the web dashboard is the interface. For console logs, use Docker or `make build-windows-server`.)

The app auto-updates when new versions are available.

Expand Down
11 changes: 11 additions & 0 deletions cmd/simulator/desktop_mode_off.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
//go:build !desktop

package main

// defaultDesktopMode is the default for the --desktop flag.
//
// Server/Docker builds omit the "desktop" build tag (e.g. the Docker image and
// the `*-server` Makefile targets). They have no display and default to the
// headless HTTP-only server. Pass --desktop (or set WAILS_DESKTOP=1) to force
// the native window.
const defaultDesktopMode = false
12 changes: 12 additions & 0 deletions cmd/simulator/desktop_mode_on.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
//go:build desktop

package main

// defaultDesktopMode is the default for the --desktop flag.
//
// Desktop release builds are compiled with the "desktop" build tag (see the
// `-tags "desktop,production"` builds for macOS, Linux and Windows). For those
// builds the app should open the native Wails window when launched with no
// arguments, so double-clicking the executable "just works". Pass
// --desktop=false (or set WAILS_DESKTOP=0) to run those builds headless.
const defaultDesktopMode = true
13 changes: 10 additions & 3 deletions cmd/simulator/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,11 @@ func main() {
mqttBasePort := flag.Int("mqtt-base", 1883, "Base port for MQTT brokers")
ocppBasePort := flag.Int("ocpp-base", 9000, "Base port for OCPP servers")
httpPort := flag.Int("http", 8762, "HTTP server port")
desktopMode := flag.Bool("desktop", false, "Run in desktop mode (Wails)")
// Default depends on the build: desktop release builds (compiled with the
// "desktop" tag) open the native window so double-clicking the executable
// works; server/Docker builds default to headless. Use --desktop=false to
// force headless on a desktop build.
desktopMode := flag.Bool("desktop", defaultDesktopMode, "Run in desktop mode (Wails window); use --desktop=false for headless server mode")
flag.Parse()

// Load settings from config file (applies before env var overrides)
Expand Down Expand Up @@ -226,9 +230,12 @@ func main() {
*httpPort = n
}
}
// WAILS_DESKTOP env var overrides flag
if os.Getenv("WAILS_DESKTOP") == "1" {
// WAILS_DESKTOP env var overrides flag/default (1 = desktop, 0 = headless)
switch os.Getenv("WAILS_DESKTOP") {
case "1":
*desktopMode = true
case "0":
*desktopMode = false
}

// Display offsets (used for UI port display)
Expand Down