You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将Python充电状态检测脚本的输出发送至PHP服务器?

Hey there! Let's walk through how to send your charger status data from your Python script to a PHP server, and set up remote access to that data. Here's a step-by-step solution that fits right into your existing code:


1. Modify Your Python Script to Send Data to the PHP Server

First, we'll add HTTP request functionality to your script using the requests library (it's simpler than built-in modules for this task). Here's the updated version of your code with data-sending logic:

import os
import ctypes
import time
from ctypes import wintypes
import winsound
import socket
import requests  # 新增:导入requests库

class SYSTEM_POWER_STATUS(ctypes.Structure):
    _fields_ = [
        ('ACLineStatus', wintypes.BYTE),
        ('BatteryFlag', wintypes.BYTE),
        ('BatteryLifePercent', wintypes.BYTE),
        ('BatteryLifeTime', wintypes.DWORD),
        ('BatteryFullLifeTime', wintypes.DWORD),
    ]

# 替换成你的PHP服务器地址(比如http://your-domain.com/receive-status.php)
SERVER_URL = "http://your-server-address/receive-status.php"
# 可选:添加API密钥防止非法提交(推荐用于公网服务器)
API_KEY = "your-secret-api-key-here"

print(socket.gethostname())
SYSTEM_POWER_STATUS_P = ctypes.POINTER(SYSTEM_POWER_STATUS)
GetSystemPowerStatus = ctypes.windll.kernel32.GetSystemPowerStatus
GetSystemPowerStatus.argtypes = [SYSTEM_POWER_STATUS_P]
GetSystemPowerStatus.restype = wintypes.BOOL

status = SYSTEM_POWER_STATUS()

while True:
    try:
        if not GetSystemPowerStatus(ctypes.pointer(status)):
            raise ctypes.WinError()
        
        # 打印本地状态
        ac_status = "YES" if status.ACLineStatus == 1 else "NO"
        print('Charger Connected: ', ac_status)
        
        if status.ACLineStatus == 0:
            winsound.Beep(2000, 1000)
            battery_removed = "Yes" if status.BatteryFlag == -128 else "No"
            if status.BatteryFlag == -128:
                print('Battery removed: ', battery_removed)
                winsound.Beep(2000, 1000)
            # 恢复系统音量
            cmd = 'nircmd.exe mutesysvolume 0 && nircmd.exe setsysvolume 65535'
            os.system(cmd)
        
        # 准备要发送到服务器的数据包
        payload = {
            "hostname": socket.gethostname(),
            "ac_line_status": status.ACLineStatus,
            "battery_flag": status.BatteryFlag,
            "timestamp": time.strftime("%Y-%m-%d %H:%M:%S"),
            "api_key": API_KEY  # 可选:身份验证字段
        }
        
        # 发送POST请求到服务器
        response = requests.post(SERVER_URL, data=payload, timeout=5)
        # 可选:打印服务器响应用于调试
        # print("Server response:", response.text)
        
    except requests.exceptions.RequestException as e:
        # 处理网络异常,避免脚本崩溃
        print(f"Failed to send data to server: {e}")
    except Exception as e:
        print(f"Unexpected error: {e}")
    
    # 调整发送频率(建议每5-10秒一次,减少服务器压力)
    time.sleep(5)

Before running this, install the requests library with:

pip install requests

2. Create the PHP Server Script to Receive and Store Data

Next, make a receive-status.php file on your web server. This script will accept the data from your Python client and store it in a MySQL database (you can use other databases too, but MySQL is common for PHP setups).

Step 2.1: Set Up the Database Table

First, create a database and table to store the status data. Run this SQL query in your MySQL admin tool (like phpMyAdmin):

CREATE TABLE device_status (
    id INT AUTO_INCREMENT PRIMARY KEY,
    hostname VARCHAR(255) NOT NULL,
    ac_line_status TINYINT NOT NULL,
    battery_flag TINYINT NOT NULL,
    timestamp DATETIME NOT NULL
);

Step 2.2: Write the Receive Script

<?php
// 替换为你的数据库配置
$servername = "localhost";
$db_username = "your-db-username";
$db_password = "your-db-password";
$db_name = "your-db-name";
$valid_api_key = "your-secret-api-key-here"; // 和Python脚本中的API_KEY一致

// 建立数据库连接
$conn = new mysqli($servername, $db_username, $db_password, $db_name);
if ($conn->connect_error) {
    die("Database connection failed: " . $conn->connect_error);
}

// 验证API密钥(可选,但推荐)
$received_api_key = $_POST['api_key'] ?? '';
if ($received_api_key !== $valid_api_key) {
    die("Invalid API key");
}

// 接收POST数据
$hostname = $_POST['hostname'] ?? '';
$ac_line_status = $_POST['ac_line_status'] ?? -1;
$battery_flag = $_POST['battery_flag'] ?? -1;
$timestamp = $_POST['timestamp'] ?? '';

// 验证数据有效性
if (!empty($hostname) && !empty($timestamp) && $ac_line_status !== -1) {
    // 使用预处理语句防止SQL注入
    $stmt = $conn->prepare("INSERT INTO device_status (hostname, ac_line_status, battery_flag, timestamp) VALUES (?, ?, ?, ?)");
    $stmt->bind_param("siss", $hostname, $ac_line_status, $battery_flag, $timestamp);
    
    if ($stmt->execute()) {
        echo "Status saved successfully";
    } else {
        echo "Error saving status: " . $stmt->error;
    }
    $stmt->close();
} else {
    echo "Invalid data received";
}

$conn->close();
?>

3. Create a PHP Script for Remote Status Reading

To view the status remotely, make a read-status.php file on your server. This script will fetch the latest status from the database and return it in JSON format (easy to read in a browser or use in other apps):

<?php
// 同样的数据库配置
$servername = "localhost";
$db_username = "your-db-username";
$db_password = "your-db-password";
$db_name = "your-db-name";

$conn = new mysqli($servername, $db_username, $db_password, $db_name);
if ($conn->connect_error) {
    die("Database connection failed: " . $conn->connect_error);
}

// 可选:按主机名筛选(比如http://your-server.com/read-status.php?hostname=YourPCName)
$target_hostname = $_GET['hostname'] ?? '';

if (!empty($target_hostname)) {
    // 获取指定主机的最新状态
    $stmt = $conn->prepare("SELECT * FROM device_status WHERE hostname = ? ORDER BY timestamp DESC LIMIT 1");
    $stmt->bind_param("s", $target_hostname);
} else {
    // 获取所有主机的最新状态
    $stmt = $conn->prepare("SELECT * FROM device_status GROUP BY hostname ORDER BY timestamp DESC");
}

$stmt->execute();
$result = $stmt->get_result();

$status_list = [];
while ($row = $result->fetch_assoc()) {
    // 转换状态为易读文本
    $row['ac_status_text'] = $row['ac_line_status'] == 1 ? "Charger Connected" : "Charger Disconnected";
    $row['battery_text'] = $row['battery_flag'] == -128 ? "Battery Removed" : "Battery Present";
    $status_list[] = $row;
}

// 返回JSON格式数据
header('Content-Type: application/json');
echo json_encode($status_list, JSON_PRETTY_PRINT);

$stmt->close();
$conn->close();
?>

4. Key Notes to Keep in Mind

  • Server Accessibility: If your server is on the public internet, ensure it has a public IP/domain and that port 80 (HTTP) or 443 (HTTPS) is open. For local networks, use your server's local IP.
  • HTTPS: For public servers, use HTTPS instead of HTTP to encrypt data in transit (you can get free SSL certificates from Let's Encrypt).
  • Frequency: Adjust the time.sleep() value in your Python script to avoid overwhelming the server (5-10 seconds is a good balance).
  • Error Handling: The Python script includes basic error handling for network issues, so it won't crash if the server is temporarily unavailable.

内容的提问来源于stack exchange,提问作者Monolica

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 09:27:24