Clean up server architecture for multi-instance deployment

- Remove main_cycling.py, main_multi.py, main_release.py (single main.py is canonical)
- Update setup.sh to read SERVICE_NAME and PORT from .env
- Update env.example with SERVICE_NAME and PORT for multi-instance support
- Fix server-csi to try rpicam-still before libcamera-still (Debian Trixie)

Deploy pattern: clone repo twice, configure each .env, run setup.sh
Each instance gets its own systemd service and install directory.
This commit is contained in:
Alex Kazaiev
2025-12-30 11:09:40 -06:00
parent 844502b4a1
commit e92b5a560b
6 changed files with 99 additions and 707 deletions

View File

@@ -142,33 +142,37 @@ class CSICameraManager:
return None
def _capture_libcamera(self) -> Optional[bytes]:
"""Fallback: use libcamera-still command"""
try:
cmd = [
"libcamera-still",
"-n", # No preview
"-o", "-", # Output to stdout
"--width", str(self.width),
"--height", str(self.height),
"-q", str(JPEG_QUALITY),
"-t", "1", # 1ms timeout (immediate capture)
]
if self.rotation:
cmd.extend(["--rotation", str(self.rotation)])
result = subprocess.run(cmd, capture_output=True, timeout=10)
if result.returncode == 0:
return result.stdout
else:
print(f"libcamera-still error: {result.stderr.decode()}")
return None
except subprocess.TimeoutExpired:
print("libcamera-still timed out")
return None
except FileNotFoundError:
# Try raspistill (older Pi OS)
return self._capture_raspistill()
"""Fallback: use rpicam-still/libcamera-still command"""
# Try rpicam-still first (Debian Trixie / newer Pi OS)
for cmd_name in ["rpicam-still", "libcamera-still"]:
try:
cmd = [
cmd_name,
"-n", # No preview
"-o", "-", # Output to stdout
"--width", str(self.width),
"--height", str(self.height),
"-q", str(JPEG_QUALITY),
"-t", "1", # 1ms timeout (immediate capture)
]
if self.rotation:
cmd.extend(["--rotation", str(self.rotation)])
result = subprocess.run(cmd, capture_output=True, timeout=10)
if result.returncode == 0:
return result.stdout
else:
print(f"{cmd_name} error: {result.stderr.decode()}")
continue
except subprocess.TimeoutExpired:
print(f"{cmd_name} timed out")
continue
except FileNotFoundError:
continue
# Fall back to raspistill (older Pi OS)
return self._capture_raspistill()
def _capture_raspistill(self) -> Optional[bytes]:
"""Legacy fallback: use raspistill command"""