Add slider sync, HTTP sensor docs, setup scripts
This commit is contained in:
parent
63af1e883b
commit
bd99b80aab
|
|
@ -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
|
||||
```
|
||||
|
|
@ -3,8 +3,8 @@
|
|||
"ipmi_username": "root",
|
||||
"ipmi_password": "calvin",
|
||||
"ipmi_port": 623,
|
||||
"http_sensor_enabled": false,
|
||||
"http_sensor_url": "",
|
||||
"http_sensor_enabled": true,
|
||||
"http_sensor_url": "http://192.168.5.200:8888",
|
||||
"http_sensor_timeout": 10,
|
||||
"enabled": true,
|
||||
"poll_interval": 10,
|
||||
|
|
@ -16,7 +16,7 @@
|
|||
"panic_on_no_data": true,
|
||||
"no_data_timeout": 60,
|
||||
"primary_sensor": "cpu",
|
||||
"sensor_preference": "ipmi",
|
||||
"sensor_preference": "auto",
|
||||
"fans": {},
|
||||
"fan_groups": {},
|
||||
"fan_curves": {
|
||||
|
|
|
|||
178
server.log
178
server.log
|
|
@ -1,61 +1,147 @@
|
|||
INFO: Started server process [896609]
|
||||
INFO: Started server process [18785]
|
||||
INFO: Waiting for application startup.
|
||||
INFO: Application startup complete.
|
||||
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:63112 - "GET /login HTTP/1.1" 200 OK
|
||||
INFO: 192.168.5.30:50547 - "GET /api/status HTTP/1.1" 401 Unauthorized
|
||||
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).
|
||||
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:49451 - "GET / 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: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).
|
||||
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
|
||||
INFO: 192.168.5.30:49451 - "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:49451 - "GET /api/status HTTP/1.1" 200 OK
|
||||
INFO: 192.168.5.30:49451 - "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 15:50:02,666 - fan_controller - ERROR - IPMI command error: [Errno 2] No such file or directory: 'ipmitool'
|
||||
2026-02-20 15:50:02,666 - fan_controller - ERROR - Failed to connect to IPMI
|
||||
INFO: 192.168.5.30:49451 - "POST /api/config/ipmi HTTP/1.1" 200 OK
|
||||
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:64565 - "GET /api/status HTTP/1.1" 200 OK
|
||||
INFO: 192.168.5.30:64565 - "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:64565 - "GET /api/status HTTP/1.1" 200 OK
|
||||
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 16:36:15,642 - fan_controller - INFO - Connected to IPMI at 192.168.5.191
|
||||
INFO: 192.168.5.30:64565 - "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).
|
||||
if datetime.utcnow() > expiry:
|
||||
INFO: 192.168.5.30:49451 - "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:49451 - "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:49451 - "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:39328 - "GET /api/status HTTP/1.1" 401 Unauthorized
|
||||
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: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 - "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).
|
||||
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: 192.168.5.30:49451 - "GET /api/status HTTP/1.1" 200 OK
|
||||
INFO: 192.168.5.30:49451 - "GET /api/status HTTP/1.1" 200 OK
|
||||
2026-02-20 15:50:24,002 - fan_controller - ERROR - IPMI command error: [Errno 2] No such file or directory: 'ipmitool'
|
||||
2026-02-20 15:50:24,002 - fan_controller - ERROR - Failed to connect to IPMI
|
||||
INFO: 192.168.5.30:49451 - "POST /api/test HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:53160 - "POST /api/auth/login 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
|
||||
2026-02-20 16:37:20,231 - fan_controller - INFO - Manual fan control enabled
|
||||
2026-02-20 16:37:20,400 - fan_controller - INFO - Connected to IPMI at 192.168.5.191
|
||||
2026-02-20 16:37:20,400 - fan_controller - INFO - HTTP sensor client initialized for http://192.168.5.200:8888
|
||||
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).
|
||||
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'
|
||||
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
|
||||
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:49451 - "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:49451 - "GET / HTTP/1.1" 200 OK
|
||||
INFO: 192.168.5.30:49451 - "GET /api/status HTTP/1.1" 200 OK
|
||||
INFO: 192.168.5.30:49451 - "GET / HTTP/1.1" 200 OK
|
||||
INFO: 192.168.5.30:49451 - "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:49451 - "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:49451 - "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:49451 - "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:49451 - "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:54102 - "GET /api/public/temperatures HTTP/1.1" 200 OK
|
||||
2026-02-20 16:37:26,052 - fan_controller - INFO - Fan 0xff speed set to 15%
|
||||
2026-02-20 16:37:26,052 - fan_controller - INFO - All fans set to 15% (Temp 27.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: 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: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: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
|
||||
|
|
|
|||
|
|
@ -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!"
|
||||
|
|
@ -751,6 +751,13 @@ def get_html(theme="dark"):
|
|||
const avgSpeed = currentStatus.current_speeds?.all || 0;
|
||||
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;
|
||||
|
||||
// Temperature grid
|
||||
|
|
|
|||
Loading…
Reference in New Issue