Add slider sync, HTTP sensor docs, setup scripts

This commit is contained in:
devmatrix 2026-02-20 16:38:34 +00:00
parent 63af1e883b
commit bd99b80aab
5 changed files with 442 additions and 49 deletions

183
SETUP.md Normal file
View File

@ -0,0 +1,183 @@
# IPMI Controller - Setup Guide
## Prerequisites
- Dell server with IPMI (iDRAC) enabled
- Linux host (Ubuntu/Debian recommended)
- Python 3.10+
- ipmitool
## Installation
### 1. Install IPMI Controller
On your management server (where you run the controller):
```bash
git clone https://github.com/yourusername/ipmi-controller.git
cd ipmi-controller
pip install -r requirements.txt
```
### 2. Install ipmitool
```bash
sudo apt-get update
sudo apt-get install -y ipmitool
```
### 3. Run the Controller
```bash
python3 web_server.py
```
Open `http://your-server:8000` in browser.
## Initial Setup
1. **Complete the Setup Wizard:**
- Create admin account
- Enter IPMI credentials
- IP: Your Dell server's IPMI IP
- Username: Usually "root"
- Password: Your IPMI password
- Port: 623 (default)
2. **Login** with your new admin credentials
## lm-sensors HTTP Server (Optional but Recommended)
For better temperature monitoring (including PCIe cards), set up lm-sensors on your Dell server:
### Option A: Automated Setup
On your **Dell/Proxmox server** (not the controller):
```bash
# Download and run setup script
curl -O https://raw.githubusercontent.com/yourusername/ipmi-controller/main/setup-sensors-server.sh
chmod +x setup-sensors-server.sh
sudo ./setup-sensors-server.sh
```
### Option B: Manual Setup
1. **Install lm-sensors:**
```bash
sudo apt-get install -y lm-sensors netcat-openbsd
```
2. **Detect sensors:**
```bash
sudo sensors-detect --auto
```
3. **Test sensors:**
```bash
sensors
```
4. **Create HTTP server script** (`/usr/local/bin/sensors-http-server.sh`):
```bash
#!/bin/bash
PORT=${1:-8888}
while true; do
{
echo -e "HTTP/1.1 200 OK\r"
echo -e "Content-Type: text/plain\r"
echo -e "Access-Control-Allow-Origin: *\r"
echo -e "\r"
sensors -u 2>/dev/null || echo "Error"
} | nc -l -p "$PORT" -q 1
done
```
5. **Make executable:**
```bash
chmod +x /usr/local/bin/sensors-http-server.sh
```
6. **Create systemd service** (`/etc/systemd/system/sensors-http.service`):
```ini
[Unit]
Description=lm-sensors HTTP Server
After=network.target
[Service]
Type=simple
ExecStart=/usr/local/bin/sensors-http-server.sh 8888
Restart=always
User=root
[Install]
WantedBy=multi-user.target
```
7. **Enable and start:**
```bash
sudo systemctl daemon-reload
sudo systemctl enable sensors-http
sudo systemctl start sensors-http
```
8. **Test:**
```bash
curl http://$(hostname -I | awk '{print $1}'):8888
```
### Configure IPMI Controller
1. Go to **Settings****HTTP** tab
2. Enable "HTTP Sensor"
3. Enter URL: `http://your-dell-server-ip:8888`
4. Save
## Docker Deployment
```bash
docker build -t ipmi-controller .
docker run -d \
-p 8000:8000 \
-v $(pwd)/data:/app/data \
--name ipmi-controller \
ipmi-controller
```
## Troubleshooting
### IPMI Connection Failed
- Verify IPMI IP is correct
- Check IPMI username/password
- Ensure IPMI is enabled in BIOS/iDRAC
- Test manually: `ipmitool -I lanplus -H <ip> -U <user> -P <pass> mc info`
### No Temperature Data
- Check if lm-sensors is installed on Dell server
- Run `sensors` to verify it works
- Check HTTP endpoint: `curl http://dell-ip:8888`
### Service Won't Start
```bash
# Check logs
sudo journalctl -u sensors-http -f
# Check if port is in use
sudo netstat -tlnp | grep 8888
```
## Security Notes
- Change default password after first login
- Use HTTPS/reverse proxy for production
- Firewall port 8000 to internal network only
- HTTP sensor endpoint is read-only
## Updating
```bash
cd ipmi-controller
git pull
pip install -r requirements.txt
# Restart the service
```

View File

@ -3,8 +3,8 @@
"ipmi_username": "root", "ipmi_username": "root",
"ipmi_password": "calvin", "ipmi_password": "calvin",
"ipmi_port": 623, "ipmi_port": 623,
"http_sensor_enabled": false, "http_sensor_enabled": true,
"http_sensor_url": "", "http_sensor_url": "http://192.168.5.200:8888",
"http_sensor_timeout": 10, "http_sensor_timeout": 10,
"enabled": true, "enabled": true,
"poll_interval": 10, "poll_interval": 10,
@ -16,7 +16,7 @@
"panic_on_no_data": true, "panic_on_no_data": true,
"no_data_timeout": 60, "no_data_timeout": 60,
"primary_sensor": "cpu", "primary_sensor": "cpu",
"sensor_preference": "ipmi", "sensor_preference": "auto",
"fans": {}, "fans": {},
"fan_groups": {}, "fan_groups": {},
"fan_curves": { "fan_curves": {

View File

@ -1,61 +1,147 @@
INFO: Started server process [896609] INFO: Started server process [18785]
INFO: Waiting for application startup. INFO: Waiting for application startup.
INFO: Application startup complete. INFO: Application startup complete.
INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit) INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
INFO: 192.168.5.30:63112 - "GET /api/status HTTP/1.1" 401 Unauthorized INFO: 192.168.5.30:50547 - "GET /api/status HTTP/1.1" 401 Unauthorized
INFO: 192.168.5.30:63112 - "GET /login HTTP/1.1" 200 OK INFO: 192.168.5.30:50547 - "GET /login HTTP/1.1" 200 OK
/home/devmatrix/projects/fan-controller-v2/web_server.py:149: DeprecationWarning: datetime.datetime.utcnow() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.datetime.now(datetime.UTC). /home/devmatrix/projects/fan-controller-v2/web_server.py:149: DeprecationWarning: datetime.datetime.utcnow() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.datetime.now(datetime.UTC).
self._sessions[token] = (username, datetime.utcnow() + timedelta(days=7)) self._sessions[token] = (username, datetime.utcnow() + timedelta(days=7))
INFO: 192.168.5.30:49451 - "POST /api/auth/login HTTP/1.1" 200 OK INFO: 192.168.5.30:64565 - "POST /api/auth/login HTTP/1.1" 200 OK
INFO: 192.168.5.30:49451 - "GET / HTTP/1.1" 200 OK INFO: 192.168.5.30:64565 - "GET / HTTP/1.1" 200 OK
/home/devmatrix/projects/fan-controller-v2/web_server.py:156: DeprecationWarning: datetime.datetime.utcnow() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.datetime.now(datetime.UTC). /home/devmatrix/projects/fan-controller-v2/web_server.py:156: DeprecationWarning: datetime.datetime.utcnow() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.datetime.now(datetime.UTC).
if datetime.utcnow() > expiry: if datetime.utcnow() > expiry:
2026-02-20 15:49:53,771 - fan_controller - INFO - Loaded config from /home/devmatrix/projects/fan-controller-v2/data/config.json 2026-02-20 16:36:09,107 - fan_controller - INFO - Loaded config from /home/devmatrix/projects/fan-controller-v2/data/config.json
INFO: 192.168.5.30:49451 - "GET /api/status HTTP/1.1" 200 OK INFO: 192.168.5.30:64565 - "GET /api/status HTTP/1.1" 200 OK
INFO: 192.168.5.30:49451 - "GET /favicon.ico HTTP/1.1" 200 OK INFO: 192.168.5.30:64565 - "GET /favicon.ico HTTP/1.1" 200 OK
INFO: 192.168.5.30:49451 - "GET /api/status HTTP/1.1" 200 OK INFO: 192.168.5.30:64565 - "GET /api/status HTTP/1.1" 200 OK
INFO: 192.168.5.30:49451 - "GET /api/status HTTP/1.1" 200 OK INFO: 192.168.5.30:64565 - "GET /api/status HTTP/1.1" 200 OK
2026-02-20 15:50:02,664 - fan_controller - INFO - Saved config to /home/devmatrix/projects/fan-controller-v2/data/config.json 2026-02-20 16:36:15,352 - fan_controller - INFO - Saved config to /home/devmatrix/projects/fan-controller-v2/data/config.json
2026-02-20 15:50:02,666 - fan_controller - ERROR - IPMI command error: [Errno 2] No such file or directory: 'ipmitool' 2026-02-20 16:36:15,642 - fan_controller - INFO - Connected to IPMI at 192.168.5.191
2026-02-20 15:50:02,666 - fan_controller - ERROR - Failed to connect to IPMI INFO: 192.168.5.30:64565 - "POST /api/config/ipmi HTTP/1.1" 200 OK
INFO: 192.168.5.30:49451 - "POST /api/config/ipmi HTTP/1.1" 200 OK INFO: 192.168.5.30:64565 - "GET /favicon.ico HTTP/1.1" 200 OK
/home/devmatrix/projects/fan-controller-v2/web_server.py:156: DeprecationWarning: datetime.datetime.utcnow() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.datetime.now(datetime.UTC). /home/devmatrix/projects/fan-controller-v2/web_server.py:156: DeprecationWarning: datetime.datetime.utcnow() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.datetime.now(datetime.UTC).
if datetime.utcnow() > expiry: if datetime.utcnow() > expiry:
INFO: 192.168.5.30:49451 - "GET /api/status HTTP/1.1" 200 OK INFO: 192.168.5.30:64565 - "GET /api/status HTTP/1.1" 200 OK
INFO: 192.168.5.30:49451 - "GET /favicon.ico HTTP/1.1" 200 OK INFO: 192.168.5.30:64565 - "GET /api/status HTTP/1.1" 200 OK
INFO: 192.168.5.30:49451 - "GET /api/status HTTP/1.1" 200 OK INFO: 192.168.5.30:64565 - "GET /api/status HTTP/1.1" 200 OK
INFO: 192.168.5.30:49451 - "GET /api/status HTTP/1.1" 200 OK INFO: 192.168.5.30:64565 - "GET /api/status HTTP/1.1" 200 OK
INFO: 192.168.5.30:49451 - "GET /api/status HTTP/1.1" 200 OK INFO: 192.168.5.30:64565 - "GET /api/status HTTP/1.1" 200 OK
INFO: 192.168.5.30:49451 - "GET /api/status HTTP/1.1" 200 OK INFO: 192.168.5.30:64565 - "GET /api/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:39328 - "GET /api/status HTTP/1.1" 401 Unauthorized INFO: 192.168.5.30:64565 - "GET /api/status HTTP/1.1" 200 OK
INFO: 192.168.5.30:49451 - "GET /api/status HTTP/1.1" 200 OK INFO: 192.168.5.30:64565 - "POST /api/test HTTP/1.1" 200 OK
/home/devmatrix/projects/fan-controller-v2/web_server.py:156: DeprecationWarning: datetime.datetime.utcnow() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.datetime.now(datetime.UTC).
if datetime.utcnow() > expiry:
INFO: 192.168.5.30:64565 - "GET /api/status HTTP/1.1" 200 OK
INFO: 192.168.5.30:64565 - "GET /api/status HTTP/1.1" 200 OK
INFO: 192.168.5.30:64565 - "GET /api/status HTTP/1.1" 200 OK
INFO: 192.168.5.30:64565 - "GET /api/status HTTP/1.1" 200 OK
INFO: 192.168.5.30:64565 - "GET /api/status HTTP/1.1" 200 OK
INFO: 192.168.5.30:64565 - "GET /api/status HTTP/1.1" 200 OK
INFO: 192.168.5.30:64565 - "GET /api/status HTTP/1.1" 200 OK
2026-02-20 16:36:59,135 - fan_controller - INFO - Saved config to /home/devmatrix/projects/fan-controller-v2/data/config.json
2026-02-20 16:36:59,301 - fan_controller - INFO - Fan 0xff speed set to 100%
INFO: 192.168.5.30:64565 - "POST /api/control/manual HTTP/1.1" 200 OK
/home/devmatrix/projects/fan-controller-v2/web_server.py:156: DeprecationWarning: datetime.datetime.utcnow() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.datetime.now(datetime.UTC).
if datetime.utcnow() > expiry:
INFO: 192.168.5.30:64565 - "GET /api/status HTTP/1.1" 200 OK
INFO: 192.168.5.30:64565 - "GET /api/status HTTP/1.1" 200 OK
INFO: 192.168.5.30:64565 - "GET /api/status HTTP/1.1" 200 OK
INFO: 192.168.5.30:64565 - "GET /api/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:42260 - "GET /api/public/temperatures HTTP/1.1" 200 OK
INFO: 192.168.5.30:64565 - "GET /api/status HTTP/1.1" 200 OK
2026-02-20 16:37:10,019 - fan_controller - INFO - Saved config to /home/devmatrix/projects/fan-controller-v2/data/config.json
2026-02-20 16:37:10,171 - fan_controller - INFO - Fan 0xff speed set to 0%
INFO: 192.168.5.30:64565 - "POST /api/control/manual HTTP/1.1" 200 OK
/home/devmatrix/projects/fan-controller-v2/web_server.py:156: DeprecationWarning: datetime.datetime.utcnow() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.datetime.now(datetime.UTC).
if datetime.utcnow() > expiry:
INFO: 192.168.5.30:64565 - "GET /api/status HTTP/1.1" 200 OK
INFO: 192.168.5.30:64565 - "GET /api/status HTTP/1.1" 200 OK
INFO: 192.168.5.30:64565 - "GET /api/status HTTP/1.1" 200 OK
2026-02-20 16:37:16,181 - fan_controller - INFO - Saved config to /home/devmatrix/projects/fan-controller-v2/data/config.json
2026-02-20 16:37:16,392 - fan_controller - INFO - Fan 0xff speed set to 13%
INFO: 192.168.5.30:64565 - "POST /api/control/manual HTTP/1.1" 200 OK
/home/devmatrix/projects/fan-controller-v2/web_server.py:156: DeprecationWarning: datetime.datetime.utcnow() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.datetime.now(datetime.UTC).
if datetime.utcnow() > expiry:
INFO: 192.168.5.30:64565 - "GET /api/status HTTP/1.1" 200 OK
INFO: 192.168.5.30:64565 - "GET /api/status HTTP/1.1" 200 OK
/home/devmatrix/projects/fan-controller-v2/web_server.py:149: DeprecationWarning: datetime.datetime.utcnow() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.datetime.now(datetime.UTC). /home/devmatrix/projects/fan-controller-v2/web_server.py:149: DeprecationWarning: datetime.datetime.utcnow() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.datetime.now(datetime.UTC).
self._sessions[token] = (username, datetime.utcnow() + timedelta(days=7)) self._sessions[token] = (username, datetime.utcnow() + timedelta(days=7))
INFO: 127.0.0.1:39340 - "POST /api/auth/login HTTP/1.1" 200 OK INFO: 127.0.0.1:53160 - "POST /api/auth/login HTTP/1.1" 200 OK
INFO: 192.168.5.30:49451 - "GET /api/status HTTP/1.1" 200 OK 2026-02-20 16:37:20,069 - fan_controller - INFO - Saved config to /home/devmatrix/projects/fan-controller-v2/data/config.json
INFO: 192.168.5.30:49451 - "GET /api/status HTTP/1.1" 200 OK 2026-02-20 16:37:20,231 - fan_controller - INFO - Manual fan control enabled
2026-02-20 15:50:24,002 - fan_controller - ERROR - IPMI command error: [Errno 2] No such file or directory: 'ipmitool' 2026-02-20 16:37:20,400 - fan_controller - INFO - Connected to IPMI at 192.168.5.191
2026-02-20 15:50:24,002 - fan_controller - ERROR - Failed to connect to IPMI 2026-02-20 16:37:20,400 - fan_controller - INFO - HTTP sensor client initialized for http://192.168.5.200:8888
INFO: 192.168.5.30:49451 - "POST /api/test HTTP/1.1" 200 OK 2026-02-20 16:37:20,401 - fan_controller - INFO - IPMI Controller service started
INFO: 127.0.0.1:53164 - "POST /api/control/auto HTTP/1.1" 200 OK
2026-02-20 16:37:20,568 - fan_controller - INFO - Manual fan control enabled
/home/devmatrix/projects/fan-controller-v2/web_server.py:156: DeprecationWarning: datetime.datetime.utcnow() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.datetime.now(datetime.UTC). /home/devmatrix/projects/fan-controller-v2/web_server.py:156: DeprecationWarning: datetime.datetime.utcnow() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.datetime.now(datetime.UTC).
if datetime.utcnow() > expiry: if datetime.utcnow() > expiry:
2026-02-20 15:50:25,685 - fan_controller - ERROR - IPMI command error: [Errno 2] No such file or directory: 'ipmitool' INFO: 192.168.5.30:64565 - "GET /api/status HTTP/1.1" 200 OK
2026-02-20 15:50:25,686 - fan_controller - ERROR - Failed to connect to IPMI
INFO: 127.0.0.1:59364 - "POST /api/test HTTP/1.1" 200 OK
/home/devmatrix/projects/fan-controller-v2/web_server.py:156: DeprecationWarning: datetime.datetime.utcnow() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.datetime.now(datetime.UTC). /home/devmatrix/projects/fan-controller-v2/web_server.py:156: DeprecationWarning: datetime.datetime.utcnow() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.datetime.now(datetime.UTC).
if datetime.utcnow() > expiry: if datetime.utcnow() > expiry:
INFO: 192.168.5.30:49451 - "GET /api/status HTTP/1.1" 200 OK INFO: 192.168.5.30:64565 - "GET /api/status HTTP/1.1" 200 OK
INFO: 192.168.5.30:49451 - "GET /api/status HTTP/1.1" 200 OK INFO: 127.0.0.1:54102 - "GET /api/public/temperatures HTTP/1.1" 200 OK
INFO: 192.168.5.30:49451 - "GET / HTTP/1.1" 200 OK 2026-02-20 16:37:26,052 - fan_controller - INFO - Fan 0xff speed set to 15%
INFO: 192.168.5.30:49451 - "GET /api/status HTTP/1.1" 200 OK 2026-02-20 16:37:26,052 - fan_controller - INFO - All fans set to 15% (Temp 27.0°C)
INFO: 192.168.5.30:49451 - "GET / HTTP/1.1" 200 OK /home/devmatrix/projects/fan-controller-v2/web_server.py:156: DeprecationWarning: datetime.datetime.utcnow() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.datetime.now(datetime.UTC).
INFO: 192.168.5.30:49451 - "GET /api/status HTTP/1.1" 200 OK if datetime.utcnow() > expiry:
INFO: 192.168.5.30:49451 - "GET /api/status HTTP/1.1" 200 OK INFO: 192.168.5.30:64565 - "GET /api/status HTTP/1.1" 200 OK
INFO: 192.168.5.30:49451 - "GET /api/status HTTP/1.1" 200 OK INFO: 192.168.5.30:64565 - "GET /api/status HTTP/1.1" 200 OK
INFO: 192.168.5.30:49451 - "GET /api/status HTTP/1.1" 200 OK INFO: 192.168.5.30:64565 - "GET /api/status HTTP/1.1" 200 OK
INFO: 192.168.5.30:49451 - "GET /api/status HTTP/1.1" 200 OK /home/devmatrix/projects/fan-controller-v2/web_server.py:156: DeprecationWarning: datetime.datetime.utcnow() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.datetime.now(datetime.UTC).
INFO: 192.168.5.30:49451 - "GET /api/status HTTP/1.1" 200 OK if datetime.utcnow() > expiry:
INFO: 192.168.5.30:49451 - "GET /api/status HTTP/1.1" 200 OK INFO: 192.168.5.30:64565 - "GET /api/status HTTP/1.1" 200 OK
INFO: 192.168.5.30:49451 - "GET /api/status HTTP/1.1" 200 OK /home/devmatrix/projects/fan-controller-v2/web_server.py:156: DeprecationWarning: datetime.datetime.utcnow() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.datetime.now(datetime.UTC).
INFO: 192.168.5.30:49451 - "GET /api/status HTTP/1.1" 200 OK if datetime.utcnow() > expiry:
INFO: 192.168.5.30:49451 - "GET /api/status HTTP/1.1" 200 OK INFO: 192.168.5.30:64565 - "GET /api/status HTTP/1.1" 200 OK
/home/devmatrix/projects/fan-controller-v2/web_server.py:149: DeprecationWarning: datetime.datetime.utcnow() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.datetime.now(datetime.UTC).
self._sessions[token] = (username, datetime.utcnow() + timedelta(days=7))
INFO: 127.0.0.1:46386 - "POST /api/auth/login HTTP/1.1" 200 OK
INFO: 127.0.0.1:46402 - "GET /api/status HTTP/1.1" 200 OK
INFO: 192.168.5.30:64565 - "GET /api/status HTTP/1.1" 200 OK
INFO: 192.168.5.30:64565 - "GET /api/status HTTP/1.1" 200 OK
INFO: 192.168.5.30:64565 - "GET /api/status HTTP/1.1" 200 OK
INFO: 192.168.5.30:64565 - "GET /api/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:49878 - "POST /api/auth/login HTTP/1.1" 200 OK
/home/devmatrix/projects/fan-controller-v2/web_server.py:156: DeprecationWarning: datetime.datetime.utcnow() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.datetime.now(datetime.UTC).
if datetime.utcnow() > expiry:
2026-02-20 16:37:51,890 - fan_controller - INFO - Saved config to /home/devmatrix/projects/fan-controller-v2/data/config.json
INFO: 127.0.0.1:49884 - "POST /api/config/settings HTTP/1.1" 200 OK
INFO: 192.168.5.30:64565 - "GET /api/status HTTP/1.1" 200 OK
/home/devmatrix/projects/fan-controller-v2/web_server.py:156: DeprecationWarning: datetime.datetime.utcnow() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.datetime.now(datetime.UTC).
if datetime.utcnow() > expiry:
INFO: 192.168.5.30:64565 - "GET /api/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:51568 - "GET /api/status HTTP/1.1" 200 OK
INFO: 192.168.5.30:64565 - "GET /api/status HTTP/1.1" 200 OK
INFO: 192.168.5.30:64565 - "GET /api/status HTTP/1.1" 200 OK
INFO: 192.168.5.30:64565 - "GET /api/status HTTP/1.1" 200 OK
/home/devmatrix/projects/fan-controller-v2/web_server.py:156: DeprecationWarning: datetime.datetime.utcnow() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.datetime.now(datetime.UTC).
if datetime.utcnow() > expiry:
INFO: 192.168.5.30:64565 - "GET /api/status HTTP/1.1" 200 OK
/home/devmatrix/projects/fan-controller-v2/web_server.py:149: DeprecationWarning: datetime.datetime.utcnow() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.datetime.now(datetime.UTC).
self._sessions[token] = (username, datetime.utcnow() + timedelta(days=7))
INFO: 127.0.0.1:60806 - "POST /api/auth/login HTTP/1.1" 200 OK
/home/devmatrix/projects/fan-controller-v2/web_server.py:156: DeprecationWarning: datetime.datetime.utcnow() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.datetime.now(datetime.UTC).
if datetime.utcnow() > expiry:
2026-02-20 16:38:11,328 - fan_controller - INFO - Saved config to /home/devmatrix/projects/fan-controller-v2/data/config.json
INFO: 127.0.0.1:60810 - "POST /api/config/settings HTTP/1.1" 200 OK
INFO: 192.168.5.30:64565 - "GET /api/status HTTP/1.1" 200 OK
2026-02-20 16:38:12,401 - fan_controller - INFO - Fan 0xff speed set to 44%
2026-02-20 16:38:12,401 - fan_controller - INFO - All fans set to 44% (Temp 52.0°C)
/home/devmatrix/projects/fan-controller-v2/web_server.py:156: DeprecationWarning: datetime.datetime.utcnow() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.datetime.now(datetime.UTC).
if datetime.utcnow() > expiry:
INFO: 192.168.5.30:64565 - "GET /api/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:40062 - "GET /api/status HTTP/1.1" 200 OK
INFO: 192.168.5.30:64565 - "GET /api/status HTTP/1.1" 200 OK
INFO: 192.168.5.30:53448 - "GET /api/status HTTP/1.1" 200 OK
/home/devmatrix/projects/fan-controller-v2/web_server.py:156: DeprecationWarning: datetime.datetime.utcnow() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.datetime.now(datetime.UTC).
if datetime.utcnow() > expiry:
INFO: 192.168.5.30:53448 - "GET /api/status HTTP/1.1" 200 OK
INFO: 192.168.5.30:53448 - "GET /api/status HTTP/1.1" 200 OK
/home/devmatrix/projects/fan-controller-v2/web_server.py:149: DeprecationWarning: datetime.datetime.utcnow() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.datetime.now(datetime.UTC).
self._sessions[token] = (username, datetime.utcnow() + timedelta(days=7))
INFO: 127.0.0.1:34550 - "POST /api/auth/login HTTP/1.1" 200 OK
2026-02-20 16:38:28,624 - fan_controller - INFO - Saved config to /home/devmatrix/projects/fan-controller-v2/data/config.json
INFO: 127.0.0.1:34556 - "POST /api/config/settings HTTP/1.1" 200 OK
INFO: 192.168.5.30:53448 - "GET /api/status HTTP/1.1" 200 OK
INFO: 192.168.5.30:53448 - "GET /api/status HTTP/1.1" 200 OK

117
setup-sensors-server.sh Normal file
View File

@ -0,0 +1,117 @@
#!/bin/bash
# IPMI Controller - lm-sensors HTTP Server Setup
# Run this on your Proxmox/Dell server to expose sensors over HTTP
set -e
echo "🌡️ IPMI Controller - lm-sensors HTTP Setup"
echo "============================================"
# Check if running as root
if [ "$EUID" -ne 0 ]; then
echo "❌ Please run as root (sudo)"
exit 1
fi
# Install lm-sensors if not present
echo ""
echo "📦 Checking lm-sensors..."
if ! command -v sensors &> /dev/null; then
echo "Installing lm-sensors..."
apt-get update
apt-get install -y lm-sensors
echo ""
echo "🔧 Running sensors-detect..."
echo "Answer YES to all questions or use default values"
sensors-detect --auto
else
echo "✓ lm-sensors already installed"
fi
# Install netcat if not present
if ! command -v nc &> /dev/null; then
echo "Installing netcat..."
apt-get install -y netcat-openbsd
fi
# Create the HTTP sensors server script
SERVER_SCRIPT="/usr/local/bin/sensors-http-server.sh"
echo ""
echo "📝 Creating HTTP server script..."
cat > "$SERVER_SCRIPT" << 'EOF'
#!/bin/bash
# lm-sensors HTTP Server for IPMI Controller
# Serves sensor data on port 8888
PORT=${1:-8888}
echo "Starting lm-sensors HTTP server on port $PORT..."
echo "Access via: http://$(hostname -I | awk '{print $1}'):$PORT"
while true; do
{
echo -e "HTTP/1.1 200 OK\r"
echo -e "Content-Type: text/plain\r"
echo -e "Access-Control-Allow-Origin: *\r"
echo -e "\r"
sensors -u 2>/dev/null || echo "Error reading sensors"
} | nc -l -p "$PORT" -q 1
done
EOF
chmod +x "$SERVER_SCRIPT"
echo "✓ Created $SERVER_SCRIPT"
# Create systemd service
SERVICE_FILE="/etc/systemd/system/sensors-http.service"
echo ""
echo "🔧 Creating systemd service..."
cat > "$SERVICE_FILE" << EOF
[Unit]
Description=lm-sensors HTTP Server for IPMI Controller
After=network.target
[Service]
Type=simple
ExecStart=$SERVER_SCRIPT 8888
Restart=always
RestartSec=5
User=root
[Install]
WantedBy=multi-user.target
EOF
echo "✓ Created $SERVICE_FILE"
# Reload systemd and enable service
echo ""
echo "🚀 Enabling and starting service..."
systemctl daemon-reload
systemctl enable sensors-http.service
systemctl start sensors-http.service
# Check status
sleep 2
if systemctl is-active --quiet sensors-http.service; then
echo "✓ Service is running!"
echo ""
echo "🌐 HTTP Endpoint: http://$(hostname -I | awk '{print $1}'):8888"
echo ""
echo "Test with: curl http://$(hostname -I | awk '{print $1}'):8888"
else
echo "⚠️ Service failed to start. Check logs:"
echo " journalctl -u sensors-http.service -f"
fi
echo ""
echo "📋 Management Commands:"
echo " Start: sudo systemctl start sensors-http"
echo " Stop: sudo systemctl stop sensors-http"
echo " Status: sudo systemctl status sensors-http"
echo " Logs: sudo journalctl -u sensors-http -f"
echo ""
echo "✅ Setup complete!"

View File

@ -751,6 +751,13 @@ def get_html(theme="dark"):
const avgSpeed = currentStatus.current_speeds?.all || 0; const avgSpeed = currentStatus.current_speeds?.all || 0;
document.getElementById('val-fans').textContent = avgSpeed + '%'; document.getElementById('val-fans').textContent = avgSpeed + '%';
// Sync slider with current speed (only if not currently dragging)
const slider = document.getElementById('manual-speed');
if (slider && document.activeElement !== slider) {{
slider.value = avgSpeed;
document.getElementById('manual-val').textContent = avgSpeed + '%';
}}
document.getElementById('val-sensors').textContent = temps.length; document.getElementById('val-sensors').textContent = temps.length;
// Temperature grid // Temperature grid