# FenixServer.Api — User Guide **FenixServer.Api** works in two ways: 1. **Embedded** — hosted inside **FenixServer**, starts and stops with the server window. 2. **Standalone console** — runs independently as `FenixServer.Api.exe`, no GUI needed. --- ## Standalone Console Mode Run FenixServer.Api directly from the command line. Ideal for headless servers, Docker, or Windows Service wrappers. ### Starting ``` FenixServer.Api.exe ``` Loads the last project from the Windows Registry and starts everything automatically. ``` FenixServer.Api.exe demo.pse ``` Loads a specific project file. ``` FenixServer.Api.exe .\projects\line1.pse ``` Full path to a project file. ### What Happens at Startup 1. Loads the project (from argument, registry, or starts empty). 2. Configures the web host on the port from the project settings (default 80). 3. Starts all communication drivers — Modbus, S7, Internal Tags, Scripts. 4. Prints a banner and status to the console. 5. Listens for HTTP requests until you press **Ctrl+C**. ### Console Output Drivers log to the console in real time: ``` [14:05:32] [INFO] [PLC_Line1] Communication started [14:05:32] [DRIVER] [PLC_Line1] started: True [14:05:32] [DRIVER] [Internal Tags] started: True [14:05:32] [DRIVER] [Scripts] started: True Server running. Press Ctrl+C to stop. ``` ![Console view](lib/fenix-web-console-view.png) ### Shutdown - **Ctrl+C** — graceful: stops all drivers, shuts down the web host, exits. - Closing the console window also triggers a clean shutdown. - Driver errors are printed to console but don't crash the server. ### Port Configuration The port comes from the project's WebServer prefix setting. If not set, defaults to **80**. --- ## Embedded Mode (via FenixServer) When FenixServer starts with a project loaded and communication running, the REST API is available automatically. The server window has a **🌐 Browser** button that opens the API in your browser. For the full server app guide, see **[FenixServer User Guide](FenixServer.md)**. --- ## 1. Before You Start 1. **FenixServer** must be running with a project loaded. 2. Communication drivers must be **started** (▶ Start). 3. Default address: `http://localhost:80` (port is set in the project configuration). --- ## 2. Quick Test ``` GET http://localhost:80/health ``` → `{"status": "healthy"}` ``` GET http://localhost:80/ ``` → `{"app": "FenixServer.Api", "status": "running", "health": "/health"}` --- ## 3. Reading Data ### Get All Tags ``` GET http://localhost:80/api/tags ``` Response (real API format): ```json [ { "tagName": "Temperature", "value": 23.5, "formattedValue": "23.50", "typeData": "Float", "areaData": "HoldingRegisters", "startData": 1, "deviceAdress": 40001, "description": "Room temperature" } ] ``` Key fields: `tagName`, `value`, `formattedValue`, `typeData`, `areaData`, `startData`, `deviceAdress`, `description`. ### Get a Single Tag ``` GET http://localhost:80/api/tags/Temperature ``` ```json { "tagName": "Temperature", "value": 23.5, "formattedValue": "23.50", "typeData": "Float" } ``` ### Get Connections ``` GET http://localhost:80/api/connections ``` Returns the same JSON format as the legacy WebServer — includes connection parameters, name, driver name, blocked/live status. ### Get Graph Data ``` GET http://localhost:80/api/graph ``` Returns time-series data for charting: ```json [ { "label": "Temperature", "data": [[1715846400000, 23.1], [1715846401000, 23.2]] }, { "label": "Humidity", "data": [[1715846400000, 58.0]] } ] ``` Each data point is `[unix_timestamp_ms, value]`. Graph data lives in server memory — it resets when the server restarts. ### Get Events ``` GET http://localhost:80/api/events ``` ```json [ { "Tm": "2026-05-16T10:00:00+00:00", "Mess": "Driver started: PLC_Line1", "frDateTime": "16.05.2026 10:00" } ] ``` Holds up to **1000 entries** — oldest are automatically removed. --- ## 4. Writing Data To set a tag value, use a **query parameter** (NOT JSON body): ``` PUT http://localhost:80/api/tags/Pump_Running?value=0 ``` Or via route: ``` PUT http://localhost:80/api/tags/Pump_Running/0 ``` | Tool | Command | |------|---------| | **cURL** | `curl -X PUT "http://localhost:80/api/tags/Pump_Running?value=0"` | | **PowerShell** | `Invoke-RestMethod -Uri "http://localhost:80/api/tags/Pump_Running?value=0" -Method Put` | > ⚠️ Writing changes the actual device. Double-check the tag address and data type first. --- ## 5. Configuring the Sampling Rate Controls how long graph data is kept (default: **100 seconds**). | Action | Request | |--------|---------| | Read interval | `GET /api/server/buffor` → `{"seconds": 100}` | | Set interval | `PUT /api/server/buffor/300` → `{"seconds": 300}` | --- ## 6. Complete Endpoint Reference ### Modern API (`/api/...`) | Method | Endpoint | Notes | |--------|----------|-------| | `GET` | `/` | Root — app name and health link | | `GET` | `/health` | Health check | | `GET` | `/api/version` | API version (`1.0`) | | `GET` | `/api/tags` | All tags: `tagName`, `value`, `formattedValue`, `typeData`, `areaData`, `startData`, `deviceAdress`, `description` | | `GET` | `/api/tags/{name}` | Single tag: `tagName`, `value`, `formattedValue`, `typeData` | | `PUT` | `/api/tags/{name}?value=X` | Set tag value via query string. Also works as `/{name}/{value}` | | `GET` | `/api/connections` | Active connections | | `GET` | `/api/graph` | `[{label, data: [[ts, val], ...]}]` | | `GET` | `/api/events` | `[{Tm, Mess, frDateTime}]` — max 1000 | | `GET` | `/api/server/buffor` | Read sampling window (seconds) | | `PUT` | `/api/server/buffor/{seconds}` | Set sampling window | | `GET` | `/api/timer/{name}` | Timer value | | `GET` | `/api/user/{name}` | User info | | `GET` | `/api/machine/{name}` | Machine info | All endpoints mirror under `/api/v1/...`. ### Legacy Endpoints Pattern: `/{obj}/{name}/{param}/{value}`. Accept both `GET` and `POST`. Return `text/plain`. | Example | What It Does | |---------|-------------| | `/Tags/All/All` | All tags as JSON array | | `/Tag/Temp/Value` | Get tag value (plain text) | | `/Tag/Temp/Value/25.5` | Set tag value | | `/Connections/All/All` | Connections JSON | | `/Graph/All/All` | Graph series JSON | | `/Events/All/All` | Events JSON | | `/Server/Buffor/Get` | Read probe counter | | `/Server/Buffor/Set/200` | Set probe counter | | `/Timer/{name}/Value` | Timer value | | `/User/{name}/Value` | User value | | `/Machine/{name}/Value` | Machine value | Legacy tag DTO fields: `tagName`, `areaData`, `startData`, `deviceAdress`, `scAdres`, `value`, `formattedValue`, `typeData`, `description`. --- ## 7. Code Examples (updated for real API) ### Python ```python import requests # Read all tags tags = requests.get("http://localhost:80/api/tags").json() for t in tags: print(f"{t['tagName']}: {t['value']} ({t['typeData']})") # Write a value (query param) requests.put("http://localhost:80/api/tags/Pump_Running?value=1") ``` ### JavaScript ```javascript // Read tags fetch("http://localhost:80/api/tags") .then(r => r.json()) .then(tags => tags.forEach(t => console.log(t.tagName, t.value))); // Write value fetch("http://localhost:80/api/tags/Pump_Running?value=0", { method: "PUT" }); ``` --- ## How It Works The REST API is an ASP.NET Core app embedded in FenixServer — no IIS, no separate process. Key points: - **CORS** fully open (`AllowAnyOrigin`) — any browser dashboard can call the API. - **Port** configured in the project settings, default 80. - **Static files** from the `Http/` project folder are served automatically — drop an `index.html` for a web dashboard. - **Authentication** — optional Basic Auth, controlled in project settings. - **Legacy compatibility** — old routes preserved byte-for-byte for existing integrations.