_headers missing, fixed

This commit is contained in:
2026-04-04 16:52:27 +02:00
parent 9cc1b695bd
commit 1907e97049
2 changed files with 117 additions and 0 deletions

107
README.md
View File

@@ -0,0 +1,107 @@
# Selsyn Gauge MQTT Controller
MQTT-based gauge controller for ESP32 / MicroPython. Drives a VID28/BKA30D/X25 stepper gauge and integrates with Home Assistant via MQTT.
## Files
| File | Description |
|------|-------------|
| `boot.py` | WiFi connect + OTA trigger |
| `ota.py` | Gitea API poller for OTA updates |
| `gaugemqtt.py` | Main MQTT controller |
| `gauge.py` | Stepper driver for VID28/BKA30D/X25 gauges |
| `config.json` | Configuration (create from `config.example.json`) |
| `config.example.json` | Template with all options |
## Deployment
```bash
# First time: upload via USB
ampy --port /dev/ttyUSB0 put boot.py
ampy --port /dev/ttyUSB0 put ota.py
ampy --port /dev/ttyUSB0 put gaugemqtt.py
ampy --port /dev/ttyUSB0 put gauge.py
ampy --port /dev/ttyUSB0 put config.json
ampy --port /dev/ttyUSB0 put lib/gauge.py /lib/gauge.py
# Monitor serial output
minicom -D /dev/ttyUSB0 -b 115200
```
## MQTT Topics
All topics are prefixed with `mqtt_prefix`:
| Topic | Direction | Description |
|-------|-----------|-------------|
| `/set` | ← | Target value from HA |
| `/state` | → | Current value |
| `/status` | → | `online`/`offline` |
| `/zero` | ← | Trigger zero calibration |
| `/led/red/set` | ← | `ON`/`OFF` |
| `/led/green/set` | ← | `ON`/`OFF` |
| `/led/backlight/set` | ← | Brightness 0-100 |
## Configuration
Copy `config.example.json` to `config.json` and edit:
### WiFi
| Key | Default | Description |
|-----|---------|-------------|
| `wifi_ssid` | — | WiFi network name |
| `wifi_password` | — | WiFi password |
### MQTT
| Key | Default | Description |
|-----|---------|-------------|
| `mqtt_broker` | — | Broker IP/hostname |
| `mqtt_port` | 1883 | Broker port |
| `mqtt_user` | — | MQTT username |
| `mqtt_password` | — | MQTT password |
| `mqtt_client_id` | — | Unique client ID |
| `mqtt_prefix` | — | Topic prefix for all MQTT messages |
### Gauge
| Key | Default | Description |
|-----|---------|-------------|
| `gauge_pins` | `[12, 13, 26, 27]` | GPIO pins (IN1, IN2, IN3, IN4) |
| `gauge_min` | 0 | Minimum value |
| `gauge_max` | 7300 | Maximum value |
| `gauge_pulse` | 4 | Pulse width in milliseconds |
| `gauge_half_step` | false | Use 8-phase half-step mode (1200 steps, smoother) |
| `smooth_step_ms` | 50 | Smooth movement interval |
| `idle_release_ms` | 3000 | Release coils after idle (ms) |
| `rezero_interval_ms` | 3600000 | Auto-rezero interval (ms, default 1hr) |
### LEDs
| Key | Default | Description |
|-----|---------|-------------|
| `led_red_pin` | 33 | Red LED GPIO pin |
| `led_green_pin` | 32 | Green LED GPIO pin |
| `led_bl_pin` | 23 | Backlight PWM GPIO pin |
### Home Assistant Discovery
| Key | Default | Description |
|-----|---------|-------------|
| `device_name` | "Selsyn 1" | Device name in HA |
| `device_model` | "Chernobyl Selsyn-inspired gauge" | Device model |
| `device_manufacturer` | "AdeBaumann" | Device manufacturer |
| `device_area` | "Control Panels" | Suggested area in HA |
| `gauge_entity_name` | "Selsyn 1 Power" | Gauge entity name |
| `gauge_unit` | "W" | Unit of measurement for gauge |
| `red_led_entity_name` | "Selsyn 1 Red LED" | Red LED entity name |
| `green_led_entity_name` | "Selsyn 1 Green LED" | Green LED entity name |
| `backlight_entity_name` | "Selsyn 1 Backlight" | Backlight entity name |
| `backlight_unit` | "%" | Unit for backlight |
### Timing
| Key | Default | Description |
|-----|---------|-------------|
| `heartbeat_ms` | 10000 | State publish interval (ms) |

10
ota.py
View File

@@ -87,6 +87,16 @@ def info(msg): _log("INFO", msg)
def warn(msg): _log("WARN", msg) def warn(msg): _log("WARN", msg)
def log_err(msg): _log("ERROR", msg) def log_err(msg): _log("ERROR", msg)
# ---------------------------------------------------------------------------
# HTTP helpers
# ---------------------------------------------------------------------------
def _headers():
h = {"Accept": "application/json"}
if API_TOKEN:
h["Authorization"] = f"token {API_TOKEN}"
return h
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
# Config loader # Config loader
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------