文章目录[隐藏]
WordPress集成教程:连接智能硬件并展示物联网设备数据面板,通过WordPress程序的代码二次开发实现常用互联网小工具功能
引言:当WordPress遇见物联网
在当今万物互联的时代,物联网设备正以前所未有的速度渗透到我们生活的方方面面。从智能家居的温度传感器到工业环境的监控设备,海量数据正源源不断地产生。然而,这些数据的价值往往受限于展示和分析的平台。与此同时,WordPress作为全球最流行的内容管理系统,已经超越了简单的博客平台,发展成为功能强大的网站构建工具。本教程将深入探讨如何将这两者结合——通过WordPress的代码二次开发,连接智能硬件并创建专业的物联网设备数据面板,同时实现多种常用互联网小工具功能。
第一部分:准备工作与环境搭建
1.1 WordPress开发环境配置
在开始集成物联网设备之前,我们需要建立一个适合开发的WordPress环境。建议使用本地开发环境如XAMPP、MAMP或Local by Flywheel,这些工具可以快速搭建包含Apache、MySQL和PHP的完整环境。
对于物联网开发,我们需要确保WordPress安装满足以下条件:
- WordPress 5.0及以上版本
- PHP 7.4及以上(建议8.0+以获得更好性能)
- 启用REST API功能
- 安装并激活调试插件,如Query Monitor和Debug Bar
1.2 物联网硬件连接基础
物联网设备与WordPress的通信通常通过以下几种方式实现:
- HTTP/HTTPS请求:设备直接向WordPress REST API端点发送数据
- MQTT协议:轻量级的发布/订阅消息传输协议,适合低带宽环境
- WebSocket连接:实现实时双向通信
- 第三方物联网平台中转:通过如ThingsBoard、AWS IoT等平台收集数据,再同步到WordPress
在本教程中,我们将主要使用HTTP REST API方式,因为它与WordPress的集成最为直接,且大多数智能硬件都支持HTTP客户端库。
1.3 必要的开发工具和库
- Postman或Insomnia:用于测试API端点
- Arduino IDE或PlatformIO:用于嵌入式设备编程
- Node-RED(可选):可视化物联网编程工具,可用于数据预处理
- Chart.js或D3.js:用于数据可视化
- Vue.js或React(可选):用于构建交互式前端面板
第二部分:创建WordPress REST API端点接收物联网数据
2.1 理解WordPress REST API架构
WordPress REST API提供了一套标准的、易于使用的接口,允许外部应用与WordPress进行数据交互。默认情况下,WordPress已经为文章、页面、用户等核心内容类型提供了API端点。
对于物联网数据,我们需要创建自定义端点来接收和存储设备数据。这可以通过两种方式实现:
- 使用
register_rest_route函数创建全新端点 - 扩展现有端点(如文章类型)来存储设备数据
2.2 创建自定义REST API端点
下面是一个完整的插件示例,用于创建接收物联网设备数据的API端点:
<?php
/**
* Plugin Name: IoT Device Data Manager
* Description: 接收和展示物联网设备数据的WordPress插件
* Version: 1.0.0
* Author: Your Name
*/
// 防止直接访问
if (!defined('ABSPATH')) {
exit;
}
class IoT_Device_Manager {
private $table_name;
public function __construct() {
global $wpdb;
$this->table_name = $wpdb->prefix . 'iot_device_data';
// 注册激活钩子
register_activation_hook(__FILE__, array($this, 'create_database_table'));
// 注册REST API路由
add_action('rest_api_init', array($this, 'register_rest_routes'));
// 注册管理菜单
add_action('admin_menu', array($this, 'add_admin_menu'));
// 注册短代码
add_shortcode('iot_dashboard', array($this, 'iot_dashboard_shortcode'));
}
// 创建数据库表
public function create_database_table() {
global $wpdb;
$charset_collate = $wpdb->get_charset_collate();
$sql = "CREATE TABLE IF NOT EXISTS {$this->table_name} (
id mediumint(9) NOT NULL AUTO_INCREMENT,
device_id varchar(100) NOT NULL,
device_type varchar(50) NOT NULL,
temperature decimal(5,2),
humidity decimal(5,2),
pressure decimal(7,2),
pm25 int(11),
voltage decimal(6,3),
status varchar(20) DEFAULT 'active',
created_at datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
INDEX device_index (device_id),
INDEX time_index (created_at)
) $charset_collate;";
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($sql);
}
// 注册REST API路由
public function register_rest_routes() {
// 接收设备数据的端点
register_rest_route('iot/v1', '/data', array(
'methods' => 'POST',
'callback' => array($this, 'handle_device_data'),
'permission_callback' => array($this, 'verify_device_token'),
'args' => array(
'device_id' => array(
'required' => true,
'validate_callback' => function($param) {
return is_string($param) && strlen($param) <= 100;
}
),
'temperature' => array(
'required' => false,
'validate_callback' => function($param) {
return is_numeric($param) && $param >= -50 && $param <= 100;
}
),
'humidity' => array(
'required' => false,
'validate_callback' => function($param) {
return is_numeric($param) && $param >= 0 && $param <= 100;
}
),
// 其他参数...
)
));
// 获取设备数据的端点
register_rest_route('iot/v1', '/data/(?P<device_id>[a-zA-Z0-9_-]+)', array(
'methods' => 'GET',
'callback' => array($this, 'get_device_data'),
'permission_callback' => function() {
return current_user_can('edit_posts');
}
));
}
// 处理设备数据
public function handle_device_data($request) {
global $wpdb;
$parameters = $request->get_params();
// 验证必要参数
if (empty($parameters['device_id'])) {
return new WP_Error('missing_device_id', '设备ID是必需的', array('status' => 400));
}
// 准备插入数据
$data = array(
'device_id' => sanitize_text_field($parameters['device_id']),
'device_type' => sanitize_text_field($parameters['device_type'] ?? 'unknown'),
'temperature' => isset($parameters['temperature']) ? floatval($parameters['temperature']) : null,
'humidity' => isset($parameters['humidity']) ? floatval($parameters['humidity']) : null,
'pressure' => isset($parameters['pressure']) ? floatval($parameters['pressure']) : null,
'pm25' => isset($parameters['pm25']) ? intval($parameters['pm25']) : null,
'voltage' => isset($parameters['voltage']) ? floatval($parameters['voltage']) : null,
'status' => 'active'
);
// 插入数据库
$result = $wpdb->insert($this->table_name, $data);
if ($result === false) {
return new WP_Error('db_insert_error', '数据插入失败', array('status' => 500));
}
// 触发数据接收动作,供其他插件使用
do_action('iot_device_data_received', $data, $wpdb->insert_id);
return rest_ensure_response(array(
'success' => true,
'message' => '数据接收成功',
'data_id' => $wpdb->insert_id,
'timestamp' => current_time('mysql')
));
}
// 验证设备令牌
public function verify_device_token($request) {
// 从请求头获取API密钥
$api_key = $request->get_header('X-IoT-API-Key');
if (empty($api_key)) {
return false;
}
// 验证API密钥(这里应该从数据库或配置中获取有效密钥)
$valid_keys = get_option('iot_valid_api_keys', array());
return in_array($api_key, $valid_keys);
}
// 获取设备数据
public function get_device_data($request) {
global $wpdb;
$device_id = $request->get_param('device_id');
$limit = $request->get_param('limit') ? intval($request->get_param('limit')) : 100;
$query = $wpdb->prepare(
"SELECT * FROM {$this->table_name} WHERE device_id = %s ORDER BY created_at DESC LIMIT %d",
$device_id,
$limit
);
$results = $wpdb->get_results($query, ARRAY_A);
if (empty($results)) {
return rest_ensure_response(array(
'success' => false,
'message' => '未找到设备数据'
));
}
return rest_ensure_response(array(
'success' => true,
'data' => $results,
'count' => count($results)
));
}
// 添加管理菜单
public function add_admin_menu() {
add_menu_page(
'物联网设备管理',
'IoT设备',
'manage_options',
'iot-device-manager',
array($this, 'display_admin_page'),
'dashicons-admin-generic',
30
);
add_submenu_page(
'iot-device-manager',
'设备数据',
'数据查看',
'manage_options',
'iot-device-data',
array($this, 'display_device_data_page')
);
}
// 显示管理页面
public function display_admin_page() {
?>
<div class="wrap">
<h1>物联网设备管理</h1>
<div class="card">
<h2>API端点信息</h2>
<p><strong>数据提交URL:</strong> <?php echo rest_url('iot/v1/data'); ?></p>
<p><strong>请求方法:</strong> POST</p>
<p><strong>内容类型:</strong> application/json</p>
<h3>请求示例</h3>
<pre>
{
"device_id": "sensor_001",
"device_type": "environment",
"temperature": 23.5,
"humidity": 65.2,
"pressure": 1013.25,
"pm25": 35
}
</pre>
</div>
</div>
<?php
}
// 短代码显示仪表板
public function iot_dashboard_shortcode($atts) {
$atts = shortcode_atts(array(
'device_id' => '',
'title' => '物联网设备数据面板',
'show_charts' => 'true'
), $atts, 'iot_dashboard');
// 生成唯一ID用于JavaScript
$dashboard_id = 'iot-dashboard-' . uniqid();
ob_start();
?>
<div id="<?php echo esc_attr($dashboard_id); ?>" class="iot-dashboard">
<h3><?php echo esc_html($atts['title']); ?></h3>
<div class="iot-stats-grid">
<div class="iot-stat-card">
<div class="stat-label">当前温度</div>
<div class="stat-value temperature">--</div>
<div class="stat-unit">°C</div>
</div>
<div class="iot-stat-card">
<div class="stat-label">当前湿度</div>
<div class="stat-value humidity">--</div>
<div class="stat-unit">%</div>
</div>
<div class="iot-stat-card">
<div class="stat-label">空气质量</div>
<div class="stat-value pm25">--</div>
<div class="stat-unit">PM2.5</div>
</div>
<div class="iot-stat-card">
<div class="stat-label">设备状态</div>
<div class="stat-value status">--</div>
<div class="stat-unit"></div>
</div>
</div>
<?php if ($atts['show_charts'] === 'true') : ?>
<div class="iot-charts-container">
<div class="chart-container">
<canvas id="<?php echo esc_attr($dashboard_id); ?>-temp-chart"></canvas>
</div>
<div class="chart-container">
<canvas id="<?php echo esc_attr($dashboard_id); ?>-humidity-chart"></canvas>
</div>
</div>
<?php endif; ?>
<div class="iot-data-table">
<table>
<thead>
<tr>
<th>时间</th>
<th>温度(°C)</th>
<th>湿度(%)</th>
<th>气压(hPa)</th>
<th>PM2.5</th>
</tr>
</thead>
<tbody>
<!-- 数据将通过JavaScript动态加载 -->
</tbody>
</table>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
// 初始化物联网仪表板
initIoTDashboard('<?php echo esc_js($dashboard_id); ?>', '<?php echo esc_js($atts['device_id']); ?>');
});
</script>
<?php
return ob_get_clean();
}
}
// 初始化插件
new IoT_Device_Manager();
// 添加前端样式和脚本
add_action('wp_enqueue_scripts', function() {
if (has_shortcode(get_post()->post_content, 'iot_dashboard')) {
// 引入Chart.js用于数据可视化
wp_enqueue_script('chart-js', 'https://cdn.jsdelivr.net/npm/chart.js', array(), '3.7.0', true);
// 引入自定义脚本
wp_enqueue_script('iot-dashboard', plugin_dir_url(__FILE__) . 'js/iot-dashboard.js', array('jquery', 'chart-js'), '1.0.0', true);
// 传递AJAX URL到前端
wp_localize_script('iot-dashboard', 'iot_ajax', array(
'ajax_url' => admin_url('admin-ajax.php'),
'rest_url' => rest_url('iot/v1/data/'),
'nonce' => wp_create_nonce('iot_nonce')
));
// 添加样式
wp_enqueue_style('iot-dashboard-style', plugin_dir_url(__FILE__) . 'css/iot-dashboard.css');
}
});
// 添加AJAX处理
add_action('wp_ajax_get_iot_data', 'handle_iot_data_ajax');
add_action('wp_ajax_nopriv_get_iot_data', 'handle_iot_data_ajax');
function handle_iot_data_ajax() {
// 验证nonce
if (!wp_verify_nonce($_POST['nonce'], 'iot_nonce')) {
wp_die('权限验证失败');
}
global $wpdb;
$table_name = $wpdb->prefix . 'iot_device_data';
$device_id = sanitize_text_field($_POST['device_id']);
$limit = intval($_POST['limit'] ?? 50);
$data = $wpdb->get_results($wpdb->prepare(
"SELECT * FROM {$table_name} WHERE device_id = %s ORDER BY created_at DESC LIMIT %d",
$device_id,
$limit
), ARRAY_A);
wp_send_json_success($data);
}
2.3 前端JavaScript代码 (iot-dashboard.js)
// iot-dashboard.js
function initIoTDashboard(dashboardId, deviceId) {
const dashboard = document.getElementById(dashboardId);
if (!dashboard) return;
// 初始化图表
let tempChart = null;
let humidityChart = null;
// 获取数据并更新仪表板
function updateDashboard() {
if (!deviceId) {
console.error('设备ID未指定');
return;
}
// 使用REST API获取数据
fetch(`${iot_ajax.rest_url}${deviceId}?limit=50`)
.then(response => response.json())
.then(data => {
if (data.success && data.data.length > 0) {
updateStats(data.data[0]); // 更新最新数据
updateCharts(data.data); // 更新图表
updateTable(data.data); // 更新表格
}
})
.catch(error => console.error('获取数据失败:', error));
}
// 更新统计数据
function updateStats(latestData) {
const tempElement = dashboard.querySelector('.temperature');
const humidityElement = dashboard.querySelector('.humidity');
const pm25Element = dashboard.querySelector('.pm25');
const statusElement = dashboard.querySelector('.status');
if (tempElement && latestData.temperature !== null) {
tempElement.textContent = latestData.temperature.toFixed(1);
// 根据温度设置颜色
tempElement.style.color = getTemperatureColor(latestData.temperature);
}
if (humidityElement && latestData.humidity !== null) {
humidityElement.textContent = latestData.humidity.toFixed(1);
}
if (pm25Element && latestData.pm25 !== null) {
pm25Element.textContent = latestData.pm25;
// 根据PM2.5设置颜色
pm25Element.style.color = getPM25Color(latestData.pm25);
}
statusElement && latestData.status) {
statusElement.textContent = latestData.status;
statusElement.className = `status status-${latestData.status}`;
}
}
// 更新图表
function updateCharts(data) {
// 反转数据,使时间从旧到新
const reversedData = [...data].reverse();
// 准备图表数据
const labels = reversedData.map(item => {
const date = new Date(item.created_at);
return `${date.getHours()}:${date.getMinutes().toString().padStart(2, '0')}`;
});
const temperatures = reversedData.map(item => item.temperature);
const humidities = reversedData.map(item => item.humidity);
// 温度图表
const tempCanvas = document.getElementById(`${dashboardId}-temp-chart`);
if (tempCanvas) {
if (tempChart) {
tempChart.destroy();
}
tempChart = new Chart(tempCanvas.getContext('2d'), {
type: 'line',
data: {
labels: labels,
datasets: [{
label: '温度 (°C)',
data: temperatures,
borderColor: 'rgb(255, 99, 132)',
backgroundColor: 'rgba(255, 99, 132, 0.1)',
tension: 0.4,
fill: true
}]
},
options: {
responsive: true,
plugins: {
legend: {
position: 'top',
},
title: {
display: true,
text: '温度变化趋势'
}
},
scales: {
y: {
beginAtZero: false,
title: {
display: true,
text: '温度 (°C)'
}
}
}
}
});
}
// 湿度图表
const humidityCanvas = document.getElementById(`${dashboardId}-humidity-chart`);
if (humidityCanvas) {
if (humidityChart) {
humidityChart.destroy();
}
humidityChart = new Chart(humidityCanvas.getContext('2d'), {
type: 'line',
data: {
labels: labels,
datasets: [{
label: '湿度 (%)',
data: humidities,
borderColor: 'rgb(54, 162, 235)',
backgroundColor: 'rgba(54, 162, 235, 0.1)',
tension: 0.4,
fill: true
}]
},
options: {
responsive: true,
plugins: {
legend: {
position: 'top',
},
title: {
display: true,
text: '湿度变化趋势'
}
},
scales: {
y: {
beginAtZero: false,
min: 0,
max: 100,
title: {
display: true,
text: '湿度 (%)'
}
}
}
}
});
}
}
// 更新数据表格
function updateTable(data) {
const tbody = dashboard.querySelector('.iot-data-table tbody');
if (!tbody) return;
tbody.innerHTML = '';
data.forEach(item => {
const row = document.createElement('tr');
const date = new Date(item.created_at);
const timeString = `${date.getFullYear()}-${(date.getMonth()+1).toString().padStart(2, '0')}-${date.getDate().toString().padStart(2, '0')} ${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}`;
row.innerHTML = `
<td>${timeString}</td>
<td>${item.temperature !== null ? item.temperature.toFixed(1) : '--'}</td>
<td>${item.humidity !== null ? item.humidity.toFixed(1) : '--'}</td>
<td>${item.pressure !== null ? item.pressure.toFixed(1) : '--'}</td>
<td>${item.pm25 !== null ? item.pm25 : '--'}</td>
`;
tbody.appendChild(row);
});
}
// 辅助函数:根据温度获取颜色
function getTemperatureColor(temp) {
if (temp < 10) return '#3498db'; // 冷 - 蓝色
if (temp < 20) return '#2ecc71'; // 凉爽 - 绿色
if (temp < 28) return '#f1c40f'; // 舒适 - 黄色
if (temp < 35) return '#e67e22'; // 温暖 - 橙色
return '#e74c3c'; // 热 - 红色
}
// 辅助函数:根据PM2.5获取颜色
function getPM25Color(pm25) {
if (pm25 <= 35) return '#2ecc71'; // 优 - 绿色
if (pm25 <= 75) return '#f1c40f'; // 良 - 黄色
if (pm25 <= 115) return '#e67e22'; // 轻度污染 - 橙色
if (pm25 <= 150) return '#e74c3c'; // 中度污染 - 红色
return '#8e44ad'; // 重度污染 - 紫色
}
// 初始加载数据
updateDashboard();
// 设置定时刷新(每30秒)
setInterval(updateDashboard, 30000);
// 添加手动刷新按钮
const refreshButton = document.createElement('button');
refreshButton.textContent = '刷新数据';
refreshButton.className = 'iot-refresh-btn';
refreshButton.onclick = updateDashboard;
const header = dashboard.querySelector('h3');
if (header) {
header.appendChild(refreshButton);
}
}
#### 2.4 前端CSS样式 (iot-dashboard.css)
/ iot-dashboard.css /
.iot-dashboard {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;
padding: 20px;
background: #f8f9fa;
border-radius: 10px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
.iot-dashboard h3 {
margin-top: 0;
color: #2c3e50;
display: flex;
justify-content: space-between;
align-items: center;
}
.iot-stats-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 20px;
margin: 20px 0;
}
.iot-stat-card {
background: white;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 5px rgba(0,0,0,0.05);
text-align: center;
transition: transform 0.3s ease;
}
.iot-stat-card:hover {
transform: translateY(-5px);
box-shadow: 0 5px 15px rgba(0,0,0,0.1);
}
.stat-label {
font-size: 14px;
color: #7f8c8d;
margin-bottom: 10px;
text-transform: uppercase;
letter-spacing: 1px;
}
.stat-value {
font-size: 36px;
font-weight: bold;
color: #2c3e50;
margin: 10px 0;
transition: color 0.3s ease;
}
.stat-unit {
font-size: 14px;
color: #95a5a6;
}
.iot-charts-container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 20px;
margin: 30px 0;
}
.chart-container {
background: white;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 5px rgba(0,0,0,0.05);
}
.iot-data-table {
margin-top: 30px;
overflow-x: auto;
}
.iot-data-table table {
width: 100%;
border-collapse: collapse;
background: white;
border-radius: 8px;
overflow: hidden;
box-shadow: 0 2px 5px rgba(0,0,0,0.05);
}
.iot-data-table th {
background: #34495e;
color: white;
padding: 15px;
text-align: left;
font-weight: 600;
}
.iot-data-table td {
padding: 12px 15px;
border-bottom: 1px solid #ecf0f1;
}
.iot-data-table tr:hover {
background: #f8f9fa;
}
.iot-refresh-btn {
background: #3498db;
color: white;
border: none;
padding: 8px 16px;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
transition: background 0.3s ease;
}
.iot-refresh-btn:hover {
background: #2980b9;
}
/ 状态指示器 /
.status-active {
color: #27ae60;
}
.status-inactive {
color: #e74c3c;
}
.status-warning {
color: #f39c12;
}
/ 响应式设计 /
@media (max-width: 768px) {
.iot-stats-grid {
grid-template-columns: repeat(2, 1fr);
}
.iot-charts-container {
grid-template-columns: 1fr;
}
}
@media (max-width: 480px) {
.iot-stats-grid {
grid-template-columns: 1fr;
}
.iot-dashboard {
padding: 10px;
}
}
### 第三部分:智能硬件端代码实现
#### 3.1 Arduino ESP8266/ESP32示例代码
// iot_sensor_to_wordpress.ino
include <ESP8266WiFi.h> // 对于ESP8266
// #include <WiFi.h> // 对于ESP32
include <ArduinoJson.h>
include <DHT.h> // 温湿度传感器库
// WiFi配置
const char* ssid = "你的WiFi名称";
const char* password = "你的WiFi密码";
// WordPress站点配置
const char* wordpress_host = "你的网站域名";
const int wordpress_port = 443; // HTTPS端口
const char* api_endpoint = "/wp-json/iot/v1/data";
const char* api_key = "你的API密钥";
// 传感器配置
define DHTPIN D4 // DHT传感器数据引脚
define DHTTYPE DHT22 // DHT22传感器类型
DHT dht(DHTPIN, DHTTYPE);
// 设备ID(每个设备唯一)
const String device_id = "sensor_001";
const String device_type = "environment";
// 定时器
unsigned long previousMillis = 0;
const long interval = 30000; // 30秒发送一次数据
void setup() {
Serial.begin(115200);
delay(1000);
Serial.println("物联网设备启动中...");
// 初始化传感器
dht.begin();
// 连接WiFi
connectToWiFi();
Serial.println("设备准备就绪");
}
void loop() {
unsigned long currentMillis = millis();
// 定时发送数据
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
// 读取传感器数据
float temperature = dht.readTemperature();
float humidity = dht.readHumidity();
// 检查读取是否成功
if (isnan(temperature) || isnan(humidity)) {
Serial.println("读取传感器数据失败");
return;
}
// 发送数据到WordPress
sendToWordPress(temperature, humidity);
}
// 其他任务...
delay(1000);
}
void connectToWiFi() {
Serial.print("连接WiFi: ");
Serial.println(ssid);
WiFi.begin(ssid, password);
int attempts = 0;
while (WiFi.status() != WL_CONNECTED && attempts < 20) {
delay(500);
Serial.print(".");
attempts++;
}
if (WiFi.status() == WL_CONNECTED) {
Serial.println("nWiFi连接成功!");
Serial.print("IP地址: ");
Serial.println(WiFi.localIP());
} else {
Serial.println("nWiFi连接失败");
}
}
void sendToWordPress(float temperature, float humidity) {
Serial.println("准备发送数据到WordPress...");
// 创建JSON数据
DynamicJsonDocument doc(256);
doc["device_id"] = device_id;
doc["device_type"] = device_type;
doc["temperature"] = temperature;
doc["humidity"] = humidity;
doc["voltage"] = getBatteryVoltage(); // 假设有电池电压读取函数
String jsonData;
serializeJson(doc, jsonData);
// 使用WiFiClientSecure进行HTTPS连接
WiFiClientSecure client;
client.setInsecure(); // 跳过证书验证(生产环境应使用证书验证)
if (!client.connect(wordpress_host, wordpress_port)) {
Serial.println("连接WordPress失败");
return;
}
// 构建HTTP请求
String request = String("POST ") + api_endpoint + " HTTP/1.1rn" +
"Host: " + wordpress_host + "rn" +
"User-Agent: IoT-Device/1.0rn" +
"X-IoT-API-Key: " + api_key + "rn" +
"Content-Type: application/jsonrn" +
"Content-Length: " + jsonData.length() + "rn" +
"Connection: closernrn" +
jsonData;
// 发送请求
client.print(request);
// 等待响应
unsigned long timeout = millis();
while (client.available() == 0) {
if (millis() - timeout > 5000) {
Serial.println("请求超时");
client.stop();
return;
}
}
// 读取响应
while (client.available()) {
String line = client.readStringUntil('r');
Serial.print(line);
}
Serial.println("n数据发送完成");
client.stop();
}
float getBatteryVoltage() {
// 模拟读取电池电压(实际实现取决于硬件)
return 3.7; // 示例值
}
#### 3.2 Raspberry Pi Python示例代码
wordpress_iot_client.py
import requests
import json
import time
import logging
from datetime import datetime
import board
import adafruit_dht # 对于DHT传感器
import psutil # 用于系统监控
配置日志
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)
class WordPressIoTClient:
def __init__(self, config):
self.config = config
self.device_id = config['device_id']
self.api_url = f"https://{config['wordpress_host']}/wp-json/iot/v1/data"
self.headers = {
'X-IoT-API-Key': config['api_key'],
'Content-Type': 'application/json'
}
# 初始化传感器
self.init_sensors()
def init_sensors(self):
"""初始化传感器"""
try:
# DHT22温湿度传感器
self.dht_device = adafruit_dht.DHT22(board.D4)
logger.info("DHT22传感器初始化成功")
except Exception as e:
logger.error(f"传感器初始化失败: {e}")
self.dht_device = None
def read_sensor_data(self):
"""读取传感器数据"""
data = {
'device_id': self.device_id,
'device_type': 'raspberry_pi',
'timestamp': datetime.now().isoformat()
}
# 读取温湿度
if self.dht_device:
try:
temperature = self.dht_device.temperature
humidity = self.dht_device.humidity
if temperature is not None and humidity is not None:
data['temperature'] = round(temperature, 2)
data['humidity'] = round(humidity, 2)
else:
logger.warning("读取传感器数据失败")
except RuntimeError as e:
logger.error(f"读取传感器错误: {e}")
# 读取系统信息
data['cpu_usage'] = psutil.cpu_percent()
data['memory_usage'] = psutil.virtual_memory().percent
data['disk_usage'] = psutil.disk_usage('/').percent
# 读取GPIO状态(示例)
data['gpio_status'] = self.read_gpio_status()
return data
def read_gpio_status(self):
"""读取GPIO状态"""
# 这里可以添加实际的GPIO读取逻辑
return {
'pin_17': 1,
'pin_18': 0,
'pin_27': 1
}
def send_data(self, data):
"""发送数据到WordPress"""
try:
response = requests.post(
self.api_url,
headers=self.headers,
json=data,
timeout=10
)
if response.status_code == 200:
logger.info(f"数据发送成功: {response.json()}")
return True
else:
logger.error(f"数据发送失败: {response.status_code} - {response.text}")
return False
except requests.exceptions.RequestException as e:
logger.error(f"请求异常: {e}")
return False
def run(self, interval=30):
"""主循环"""
logger
